c++11右值引用的绑定规则

右值引用的绑定规则

右值引用(rvalue reference,&&)跟传统意义上的引用(reference,&)很相似,为了更好地区分它们俩,传统意义上的引用又被称为左值引用(lvalue reference)。下面简单地总结了左值引用和右值引用的绑定规则(函数类型对象会有所例外):

(1)非const左值引用只能绑定到非const左值;

(2)const左值引用可绑定到const左值、非const左值、const右值、非const右值;

(3)非const右值引用只能绑定到非const右值;

(4)const右值引用可绑定到const右值和非const右值。

测试例子如下:

struct A { A(){} };
A lvalue;                             // 非const左值对象
const A const_lvalue;                 // const左值对象
A rvalue() {return A();}              // 返回一个非const右值对象
const A const_rvalue() {return A();}  // 返回一个const右值对象

// 规则一:非const左值引用只能绑定到非const左值
A &lvalue_reference1 = lvalue;         // ok
A &lvalue_reference2 = const_lvalue;   // error
A &lvalue_reference3 = rvalue();       // error
A &lvalue_reference4 = const_rvalue(); // error

// 规则二:const左值引用可绑定到const左值、非const左值、const右值、非const右值
const A &const_lvalue_reference1 = lvalue;         // ok
const A &const_lvalue_reference2 = const_lvalue;   // ok
const A &const_lvalue_reference3 = rvalue();       // ok
const A &const_lvalue_reference4 = const_rvalue(); // ok

// 规则三:非const右值引用只能绑定到非const右值
A &&rvalue_reference1 = lvalue;         // error
A &&rvalue_reference2 = const_lvalue;   // error
A &&rvalue_reference3 = rvalue();       // ok
A &&rvalue_reference4 = const_rvalue(); // error

// 规则四:const右值引用可绑定到const右值和非const右值,不能绑定到左值
const A &&const_rvalue_reference1 = lvalue;         // error
const A &&const_rvalue_reference2 = const_lvalue;   // error
const A &&const_rvalue_reference3 = rvalue();       // ok
const A &&const_rvalue_reference4 = const_rvalue(); // ok

// 规则五:函数类型例外
void fun() {}
typedef decltype(fun) FUN;  // typedef void FUN();
FUN       &  lvalue_reference_to_fun       = fun; // ok
const FUN &  const_lvalue_reference_to_fun = fun; // ok
FUN       && rvalue_reference_to_fun       = fun; // ok
const FUN && const_rvalue_reference_to_fun = fun; // ok

【说明】:(1) 一些支持右值引用但版本较低的编译器可能会允许右值引用绑定到左值,例如g++4.4.4就允许,但g++4.6.3就不允许了,clang++3.2也不允许,据说VS2010 beta版允许,正式版就不允许了,本人无VS2010环境,没测试过。

(2)右值引用绑定到字面值常量同样符合上述规则,例如:int &&rr = 123;,这里的字面值123虽然被称为常量,可它的类型为int,而不是const int。对此C++03标准文档4.4.1节及其脚注中有如下说明:

If T is a non-class type, the type of the rvalue is the cv-unqualified version of T.

In C++ class rvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues never have cv-qualified types.

因此123是非const右值,int &&rr = 123;语句符合上述规则三。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值