模板允许左值与右值引用绑定

时间:2018-10-08 14:08:45

标签: c++ c++11 move-semantics 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正确的行走”。

为什么? T工作时采用哪种类型?这不是击败右值引用的对象吗?

2 个答案:

答案 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& ); 绑定到左值引用。