模板允许左值与右值引用绑定
Template allows lvalue to become bound with rvalue reference
这个程序:
using namespace std;
#include <iostream>
#include <memory>
struct Dog
{
int legs;
} adog;
Dog gimmeadog() { return adog; }
void walk(Dog && d) { cout << "Nonconst right dog walk\n"; }
//template<class T> void walk(T && d) { d.legs=3; cout << "Nonconst right something walk\n"; }
int main() {
Dog mydog = gimmeadog();
walk(mydog);
return 0;
}
正确地无法在 gcc 上编译,因为:
error: cannot bind rvalue reference of type ‘Dog&&’ to lvalue of type ‘Dog’
walk(mydog);
但如果您取消对模板的注释,它会愉快地绑定并打印 "Nonconst right something walk"。
为什么? T
工作时采用什么类型?这不是破坏了右值引用的对象吗?
template<class T>
void walk(T && d)
在这种情况下T&&是转发引用,当你传递左值(mydog
对象)时T
被推导为T&
,所以 walk
的签名看起来像
void walk(Dog& );
然后您可以将 mydog
绑定到左值引用。
当 T
是模板参数时 T&&
是 forwarding reference,而不是右值参数。 T
对于 r 值推导为 T
,对于 l 值推导为 T&
。这样的引用绑定到任何东西。
这个程序:
using namespace std;
#include <iostream>
#include <memory>
struct Dog
{
int legs;
} adog;
Dog gimmeadog() { return adog; }
void walk(Dog && d) { cout << "Nonconst right dog walk\n"; }
//template<class T> void walk(T && d) { d.legs=3; cout << "Nonconst right something walk\n"; }
int main() {
Dog mydog = gimmeadog();
walk(mydog);
return 0;
}
正确地无法在 gcc 上编译,因为:
error: cannot bind rvalue reference of type ‘Dog&&’ to lvalue of type ‘Dog’
walk(mydog);
但如果您取消对模板的注释,它会愉快地绑定并打印 "Nonconst right something walk"。
为什么? T
工作时采用什么类型?这不是破坏了右值引用的对象吗?
template<class T>
void walk(T && d)
在这种情况下T&&是转发引用,当你传递左值(mydog
对象)时T
被推导为T&
,所以 walk
的签名看起来像
void walk(Dog& );
然后您可以将 mydog
绑定到左值引用。
当 T
是模板参数时 T&&
是 forwarding reference,而不是右值参数。 T
对于 r 值推导为 T
,对于 l 值推导为 T&
。这样的引用绑定到任何东西。