vendredi 24 avril 2015

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.

Aucun commentaire:

Enregistrer un commentaire