不能在成员函数中将左值绑定到右值,但在全局函数中可以
在查看std::forward的参考页面时,我遇到了一些奇怪的事情。该示例将左值作为右值引用传递......但传递给全局函数......并且它编译并运行。我尝试了与成员函数相同的事情,但无法编译。是什么赋予了?我希望两个调用在不使用std::moveor 的情况下都会失败std::forward<T>。
#include <iostream>
template <typename T>
void globalDoSomething(T &&data) {
std::cout << "We're doing it!!" << std::endl;
}
template <typename T>
class A {
public:
void doSomething(T &&data);
};
template <typename T>
void A<T>::doSomething(T &&data)
{
std::cerr << "Ah, man. I won't compile." << std::endl;
}
template class A<int>;
int main()
{
int b = 0;
globalDoSomething(b);
A<int> a;
a.doSomething(b);
return 0;
}
回答
这是因为自动模板推导globalDoSomething推断T为int&.
如果您globalDoSomething<int>(b);像对模板类的成员函数那样显式实例化模板函数,它也将无法编译。
相反,如果您使用 实例化模板类A<int&> a;,它将成功编译。
- In other words, it's not actually an rvalue reference, but a so-called "forwarding reference" (or "universal reference" in older parlance). Though its magic is powered by pretty normal rules (as Patrick has pointed out), we tend to think of a `T&&` with template `T` as being its own special thing, because it's convenient to do so.