通常情况下,右值引用不能绑定左值,如果想绑定左值,需要用std::move()将左值转为将亡值。
int main(){
int a = 10;
int && b = move(a);//没有move()则:error: cannot bind 'int' lvalue to 'int&&'|
cout<<a<<" "<<b<<endl;
return 0;
}
输出10 10
;
特殊情况下使用auto
或者template<typename T>
发生自动类型推断的时候,&& t
可能会成为 普通引用 或 常量引用 或者 右值引用 。
如果传入普通左值a,那么b的类型会被推导成左值引用。
比如:
int main(){
int a = 10;
auto && b = a;
cout<<a<<" "<<b;
b++;
cout<<a<<" "<<b<<endl;
return 0;
}
同样输出10 10 11 11
,此时b是普通左值引用。
如果传入常量引用a
int main(){
const int& a = 10;
auto && b = a;
cout<<a<<" "<<b<<endl;
//b++;//error: increment of read-only reference 'b'|
return 0;
}
输出10 10
,且无法更改b,说明了b是常量引用。
如果传入右值引用10
int main(){
auto && b = 10;
cout<<b;
b++;
cout<<b<<endl;
return 0;
}
输出10 11
,此时b是10的右值引用,且可以修改b的值。
即在发生自动类型推断的时候,&&
只是表面,实际上是什么引用,取决于用于引用的对象。
事实上auto
除了一个特例以外与模版推导类型别无二致
特例:auto x = {1}或者auto x = {1, 2}会被推断成std::initializer_list,而template会直接出错