品牌高端网站建设,金戈西地那非片,做网站的技术风险,做任务赚q币网站右值和右值的区别 C11 中右值可以分为两种#xff1a;一个是将亡值#xff08; xvalue, expiring value#xff09;#xff0c;另一个则是纯右值#xff08; prvalue, PureRvalue#xff09;#xff1a; 纯右值#xff1a;非引用返回的临时变量、运算表达式产生的临时变…右值和右值的区别 C11 中右值可以分为两种一个是将亡值 xvalue, expiring value另一个则是纯右值 prvalue, PureRvalue 纯右值非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和 lambda 表达式等 将亡值与右值引用相关的表达式比如T类型函数的返回值、 std::move 的返回值等。 区分左值与右值的便捷方法是可以对表达式取地址就是左值否则为右值 。所有有名字的变量或对象都是左值而右值是匿名的。
但右值引用延长了右值的生命周期使用上相当于左值。 例子1
#include iostream
using namespace std;int main()
{//左值int num 9;//左值引用int a num;//右值//右值引用int b 8;//常量左值引用const int C num;//常量右值引用const int d 6;/*const int e b; // error,右值引用只能通过右值初始化int f b // error,右值引用只能通过右值初始化*/// 右值引用延长了右值的生命周期相当于左值可以给常量左值引用赋值。const int g b;const int h d;const int i a;int j b;return 0;
};
规则
右值引用延长了右值的生命周期使用上相当于左值。左值不能初始化右值引用。右值只能初始化右值引用。 的特性
例子2
templatetypename T
void f(T param);
void f1(const T param);
f(10);
int x 10;
f(x);
f1(x); // error, x是左值,左值不能初始化右值引用
f1(10); // ok, 10是右值
在上面的例子中函数模板进行了自动类型推导需要通过传入的实参来确定参数param的实际类型。 第4行中对于f(10)来说传入的实参10是右值因此T表示右值引用 第6行中对于f(x)来说传入的实参是x是左值因此T表示左值引用 第7行中f1(x)的参数是const T不是未定引用类型不需要推导本身就表示一个右值引用 由于上述代码中存在 T 或者 auto 这种未定引用类型当它作为参数时有可能被一个右值引用初始化也有可能被一个左值引用初始化在进行类型推导时右值引用类型会发生变化这种变化被称为引用折叠。在C11中引用折叠的规则如下
通过右值推导 T 或者 auto得到的是一个右值引用类型通过非右值右值引用、左值、左值引用、常量右值引用、常量左值引用推导 T 或者 auto 得到的是一个左值引用类型另外还有一点需要额外注意 const T 表示一个右值引用不是未定引用类型不需要推导。 例子3
int a1 5;
auto bb a1;
auto bb1 5;int a2 5;
int a3 a2;
auto cc a3;
auto cc1 a2;const int s1 100;
const int s2 100;
auto dd s1;
auto ee s2;const auto x 5; //type(x) const int xint gg 5;
auto ii gg; // type(ii) int iiint hh gg; // 错误gg是右值引用使用上相当于左值左值不可以初始化右值引用
int hh move(gg); // ok,通过move()函数进行了资源的转移将左值转换为了右值。
第2行a1为右值引用推导出的bb为左值引用类型第3行5为右值推导出的bb1为右值引用类型第7行a3为左值引用推导出的cc为左值引用类型第8行a2为左值推导出的cc1为左值引用类型第12行s1为常量左值引用推导出的dd为常量左值引用类型第13行s2为常量右值引用推导出的ee为常量左值引用类型第15行x为右值引用不需要推导只能通过右值初始化 参考链接
爱编程的大丙-右值引用 爱编程的大丙-转移和完美转发