Arun
Arun

Reputation: 3408

Preserving referenceness when passing variadic arguments

Consider the following code snippet:

class Base
{
public:

    template <typename...Ts>
    void fun(Ts... vs)
    {
        cout << "Base::fun" << endl;
        cout << __FUNCSIG__ << endl;
    }
};

template <typename...Ts>
class Derived : public Base
{
public:
    void dfun(Ts... vs)
    {
        cout << "Derived::dfun" << endl;
        cout << __FUNCSIG__ << endl;
        fun(vs...);
    }
};

int main()
{
    int i = 10;
    int & a = i;
    Derived<int, int &> d;
    d.dfun(i, a);
}

On running the above code in VS2013, I get the types deduced for paramater pack values in Derived::dfun is (int, int&) where as in Base::fun is (int, int). Why is the referenceness lost when passing the arguments?

If dfun and fun were free functions, the referenceness is preserved. Why this difference?

If I change the signature of Base::fun to Base::fun(Ts&&... vs), the referenceness is preserved again.

Upvotes: 1

Views: 111

Answers (1)

phantom
phantom

Reputation: 3342

During template deduction reference types will deduced to the type that they refer to. So int& will be deduced to an int. This is what is causing the behaviour you are seeing.

See here for a more detailed explication.

Upvotes: 2

Related Questions