关于左值、将亡值和纯右值

C++11之前,表达式的值分为左值和右值两种,其中右值就是我们理解中的字面值1、true、NULL等。
C++11开始,表达式的值分为左值(lvalue, left value)、将亡值(xvalue, expiring value)、纯右值(pvalue, pure ravlue)

一、如何判断左值、将亡值和纯右值

左值、将亡值和纯右值的概念比较烧脑,本文首先给出一个简单的方法来用做判定这三者:

int a = 1;
cout << type_id_with_cvr<decltype((a))>().pretty_name() << endl; // int&
cout << type_id_with_cvr<decltype((std::move(a)))>().pretty_name() << endl; // int&&
cout << type_id_with_cvr<decltype((1))>().pretty_name() << endl; // int
  • decltype((expr))的返回值是T&, 那么expr是一个左值
  • decltype((expr))的返回值是T&&, 那么expr是一个将亡值
  • decltype((expr))的返回值是T, 那么expr是一个纯右值

二、左值、将亡值和纯右值对与函数调用的影响

首先,我们来看一下三者对于左值引用传参的影响:

void test(int&){
    cout << __PRETTY_FUNCTION__ << endl;
}

test(a);
test(std::move(a));	// no matching function for call to 'test'
test(1);	// no matching function for call to 'test'

可以看到左值引用的传参方式,无法接收expr为将亡值和纯右值, 需要提到的一点是,如果表达式为const int&,那么三种传递方式都是合法的:

void test(const int&){
    cout << __PRETTY_FUNCTION__ << endl;
}

test(a);			// void test(const int &)
test(std::move(a));	// void test(const int &)
test(1);			// void test(const int &)

如果传参方式为右值引用传参,那么情况如下:

void test(int&&){
    cout << __PRETTY_FUNCTION__ << endl;
}

test(a);			// no matching function for call to 'test'
test(std::move(a));	
test(1);			 

如果上述三种传参方式都存在的话, 情况如下:

test(a);				// void test(int &)
test(std::move(a));		// void test(int &&)
test(1);				// void test(int &&)

总结

  1. 左值引用和右值引用得传参优先级别都高于常量引用
  2. 拷贝传参无法与上述三者任一共存,否则报错(call to 'test' is ambiguous)

参考

  1. 关于c++的左值和右值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值