我是靠谱客的博主 诚心汽车,最近开发中收集的这篇文章主要介绍c++ 值类型之右值,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

总之,在c++表达式不是左值,就是右值。

右值的特性:

1 右值不能取址,如&i++是无法编译的

2 右值不能赋值,即不能作为内建的赋值运算符和复合赋值运算符的左操作数。注意:此处强调的是内建,因为c++支持运算符重载,重载过的赋值运算符和复合赋值运算符,右值仍然可以作为左操作数

3. 右值可以初始化const左值引用(左值介绍参见https://blog.csdn.net/ant2012/article/details/91345255),且右值所标识的对象的生命周期会延长到该引用的作用域结尾

4. 右值可以初始化右值引用,且右值所标识的对象的生命周期会延长到该引用的作用域结尾

5. 在函数重载的情况下,一个是右值引用形参,一个是const左值引用形参,右值优先匹配右值引用


class Test {
public:
void operator = (int i) {
}
};
Test getTest() {
return Test();
}
int getInt() {
return 0;
}
int main(int argc, const char * argv[]) {
getTest() = 1; // valid
getInt() = 1;
// invalid, build error
const int& i = getInt(); // valid
int&& i = getInt(); // valid
return 0;
}

右值包含纯右值和亡值

纯右值:

1. 除了字符串之外的字面量。如42,true,nullptr

2. 返回类型为非引用的函数调用或运算符重载表达式。如str.substr(1, 2), str1 + str2

3. 内建的后置自增和自减表达式。如i++,i--

4. 内建的算术表达式。如i + j,i * j,i - j

5. 内建的逻辑表达式。如 i && i,i || j

6. 内建的比较表达式。如 i < j,i == j

7. 内建的取址表达式。如 &a

8. 对象成员表达式。如a.m,且m是成员枚举项(不是枚举变量)或者是非静态成员函数(参见下面的未决成员函数调用),或者a为右值且m为非引用类型的非静态数据成员。代码demo参见https://blog.csdn.net/ant2012/article/details/91345255第7条

9. 内建的指针成员表达式,如p->m,且m是成员枚举项(不是枚举变量)或者是非静态成员函数(参见下面的未决成员函数调用)

10. 对象的成员指针表达式,如a.*mp,且mp是成员函数指针(参见下面的未决成员函数调用),或者a是右值且mp是数据成员指针(c++11之前,c++11以后被归为亡值)

typedef int (Test::*MP); // 数据成员指针
MP mp = &Test::value;
getTest().*mp; // 右值

11. 内建的指针的指针成员表达式,如p->*m,且mp是成员函数指针(参见下面的未决成员函数调用)

12. 内建的逗号表达式,如a, b,其中b是右值,因为逗号表达式的值就是最后一个表达式的值

13. 三元条件表达式,即 a ? b : c,至于其什么情况为右值,详见条件表达运算符,个人经验是当b和c都是左值时,表达式才是左值,否则是右值(纯右值或亡值)

14. 转换为非引用类型的转型表达式,如static_cast<double>(x),(int)1

15. this指针

16. 枚举项(不是枚举变量)

17. 非类型模板形参,且其类型不能是类(c++20),也不能是左值引用

18. lambda表达式,如 [] () {std::cout << "qianll" << std::endl;}

19. requires表达式(c++20)

亡值:

1. 函数调用或重载运算符表达式,其返回类型为右值引用,如std::move(x)

2. 内建的下标表达式,如a[n],且a为右值

3. 对象成员表达式,如a.m,且a为右值,且m是非静态的非引用类型

4. 对象的成员指针表达式,如a.*mp,且a为右值且mp是数据成员指针

5. 三元条件表达式,即 a ? b : c,至于其什么情况为亡值,详见条件表达运算符,个人经验是当b和c都是左值时,表达式才是左值,否则是右值(纯右值或亡值)

6. 转换为右值引用的转型表达式,例如static_cast<int&&>(x)

7. c++17部分case

未决成员函数调用(Pending member function call)

表达式 a.mf 与 p->mf,其中 mf 是非静态成员函数,以及表达式 a.*pmf 与 p->*pmf,其中 pmf 是成员函数指针,被归类为纯右值表达式。但它们不能用来初始化引用,也不能作为实参,只能用来作为函数调用运算符的左操作数(即p.mf(args)),总之我理解的就是无法验证它是右值,但是它就是右值

参考:https://en.cppreference.com/w/cpp/language/value_category

加入我们:http://www.duoceshi.com/team.html

最后

以上就是诚心汽车为你收集整理的c++ 值类型之右值的全部内容,希望文章能够帮你解决c++ 值类型之右值所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部