模板函数未使用右值引用实例化/接收调用

时间:2019-05-10 18:24:41

标签: c++

如标题中所述,当我显式实例化函数的左值和右值版本时,如果我尝试使用模板来这样做,则不会。 gcc 7.4。我想念什么?

class Test {};

class Explicit {
public:
    void func (const Test &t) {
        cout << std::is_rvalue_reference<const Test&>::value << endl;
    }

    void func (Test &&t) {
        cout << std::is_rvalue_reference<Test&&>::value << endl;
    }
};

class Implicit {
public:
    template<class T>
    void func (T t) {
        cout << std::is_rvalue_reference<T>::value << endl;
    }
};

// explicitly instantiate two versions of the function
template void Implicit::func<const Test &> (const Test &);
template void Implicit::func<Test &&> (Test &&);

int main () {
    Explicit e = Explicit ();
    Implicit i = Implicit ();
    Test t;

    e.func (t);                 // goes to func (const Test&), as expected
    e.func (Test ());           // goes to func (Test&&), as expected
    e.func ((Test &&) Test ()); // goes to func (Test&&), as expected

    i.func (t);                 // goes to func (const Test&), as expected
    i.func (Test ());           // goes to func (const Test&), not as expected!
    i.func ((Test &&) Test ()); // goes to func (const Test&), not as expected!
}

2 个答案:

答案 0 :(得分:2)

使用转发引用和decltype。

class Implicit {
public:
    template<class T>
    void func (T&& t) {
        cout << std::is_rvalue_reference<decltype(t)>::value << endl;
    }
};

答案 1 :(得分:1)

您的显式实例化是没有用的(在拆分标头和cpp时可能会有用):

// explicitly instantiate two versions of the functions
template void Implicit::func<const Test &> (const Test &);
template void Implicit::func<Test &&> (Test &&);

实际上,您的“隐含”是:

i.func (t);                 // goes to func(Test)
i.func (Test ());           // goes to func(Test)
i.func ((Test &&) Test ()); // goes to func(Test)

template<class T> void func (T t)

不推论参考。

您先致电void Implicit::func<Test>