该程序:
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正确的行走”。
为什么? T
工作时采用哪种类型?这不是击败右值引用的对象吗?
答案 0 :(得分:9)
当T
是模板参数时,T&&
是forwarding reference,而不是r值。对于r值,将T
推导出为T
,对于l值,将得出T&
。这样的引用可以绑定任何东西。
答案 1 :(得分:5)
template<class T>
void walk(T && d)
在这种情况下, T && 是转发引用,当您传递左值(mydog
对象)T
时被推导为T&
,因此{{ 1}}看起来像
walk
然后您可以将void walk(Dog& );
绑定到左值引用。