表达式左值右值(C++学习) 区分? const vs non-const 右值引用 移动语义:报错-问答-阿里云开发者社区-阿里云

开发者社区> 问答> 正文

表达式左值右值(C++学习) 区分? const vs non-const 右值引用 移动语义:报错

2020-06-06 19:55:43 290 1

左值右值是表达式的属性,该属性称为 value category。按该属性分类,每一个表达式属于下列之一:

lvalue

left value,传统意义上的左值

xvalue

expiring value, x值,指通过“右值引用”产生的对象

prvalue

pure rvalue,纯右值,传统意义上的右值(?)

而 xvalue 和其他两个类型分别复合,构成:

lvalue + xvalue = glvalue

general lvalue,泛左值

xvalue + prvalue = rvalue

右值

区分?

++x 与 x++ 假定x的定义为 int x=0;,那么前者是 lvalue,后者是rvalue。前者修改自身值,并返回自身;后者先创建一个临时对像,为其赋值,而后修改x的值,最后返回临时对像。

区分表达式的左右值属性有一个简便方法:若可对表达式用 & 符取址,则为左值,否则为右值。比如

&obj , &*ptr , &ptr[index] , &++x

有效

&1729 , &(x + y) , &std::string("meow"), &x++

无效

对于函数调用,根绝返回值类型不同,可以是lvalue、xvalue、prvalue:

  • The result of calling a function whose return type is an lvalue reference is an lvalue

  • The result of calling a function whose return type is an rvalue reference is an xvalue.

  • The result of calling a function whose return type is not a reference is a prvalue.

const vs non-const

左值和右值表达式都可以是const或non-const。

比如,变量和函数的定义为:

string one("lvalue");
const string two("clvalue");
string three() { return "rvalue"; }
const string four() { return "crvalue"; }

那么表达式:

表达式

分类

one

modifiable lvalue

two

const lvalue

three()

modifiable rvalue

four()

const rvalue

引用

Type&

只能绑定到可修改的左值表达式

const Type&

可以绑定到任何表达式

Type&&

可绑定到可修改的左值或右值表达式

const Type&&

可以绑定到任何表达式

重载函数

#include <iostream>
#include <string>
using namespace std;

string one("lvalue");
const string two("clvalue");
string three() { return "rvalue"; }
const string four() { return "crvalue"; }

void func(string& s)
{
    cout << "func(string& s): " << s << endl;
}

void func(const string& s)
{
    cout << "func(const string& s): " << s << endl;
}

void func(string&& s)
{
    cout << "func(string&& s): " << s << endl;
}

void func(const string&& s)
{
    cout << "func(const string&& s): " << s << endl;
}

int main()
{
    func(one);
    func(two);
    func(three());
    func(four());
    return 0;
}

结果:

func(string& s): lvalue
func(const string& s): clvalue
func(string&& s): rvalue
func(const string&& s): crvalue

如果只保留const string& 和 string&& 两个重载函数,结果为:

func(const string& s): lval
C++
取消 提交回答
全部回答(1)
  • kun坤
    2020-06-06 19:55:51

    lz你好,右值引用当中:

    int main() {  int && a=1;  F2(a);  F1(a);  F2(2);  F1(2);  return 0; }

    F2(a)会出现编译错误,因为具名右值引用传参时会作为左值,而F2中的参数int &&a 只能绑定非常量右值,而不能绑定左值。

    还有你说“对函数的右值引用无论具名与否都将被视为左值”,经过试验只有具名函数的右值引用才会作为左值,而非具名则会作为右值.

    试验代码:

    #include<iostream>
    #include<algorithm>
    using std::cout;
    using std::endl;
    void F1(int &a)
    {
    cout<<"左值引用"<<endl;
    }
    void F1(int && a)
    {
    cout<<"右值引用"<<endl;
    }
    int test()
    {
    return 1;
    }


    int main()
    {
      int &&a = test();//具名函数右值引用
    F1(a);//非常量左值引用只能绑定非常量左值,所以具名函数右值引用会作为左值调用F1(int &a)
    F1(test());//非常量右值引用只能1绑定非常量右值,所以非具名函数作为右值调用F1(int &&a)


    return 0;
    }
    模板参数类型当中:

    template <typename Type> void Swap(Type&& sb1, Type&& sb2) {  Type sb(sb1);  sb1 = sb2;  sb2 = sb; }
    sb1和sb都是非常量右值引用,他们是不能绑定作为左值的具名右值引用的。

    参见博客:http://www.cnblogs.com/hujian/archive/2012/02/13/2348621.html

    0 0
相关问答

40

回答

[@徐雷frank][¥20]什么是JAVA的平台无关性

大河人家 2018-10-29 23:55:20 144754浏览量 回答数 40

53

回答

OSS C/C++ SDK分享交流区

否极泰来 2015-06-15 17:05:09 48073浏览量 回答数 53

3

回答

安全狗VS云锁

ap0453m0g 2014-11-09 16:20:00 15598浏览量 回答数 3

10

回答

windows版本oss c sdk如何上传和下载包含中文名的文件

yjseu 2015-11-20 17:14:30 15954浏览量 回答数 10

1

回答

【开源分享】-4期 Notepads 一款国人开发的UWP超好用文本编辑器

montos 2020-05-06 13:34:43 28973浏览量 回答数 1

58

回答

技术入门问答集锦,涉及多种技术方向,解决新人学习困惑

管理贝贝 2016-08-03 10:13:27 52764浏览量 回答数 58

4

回答

上传到OSS的文件md5hash值如何获取?!!

asker 2015-08-05 16:52:10 21277浏览量 回答数 4

38

回答

【论战!】访问压力大,你会选择升级ECS配置or选择再买1台ECS做负载均衡SLB

qilu 2014-12-25 17:32:40 20811浏览量 回答数 38

12

回答

电信云VS阿里云

米蛋 2013-12-13 23:25:52 15993浏览量 回答数 12

23

回答

【云服务器分享】网站访问速度快才是硬道理

dreamdoo 2012-10-15 10:15:02 85377浏览量 回答数 23
+关注
0
文章
13401
问答
问答排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载