您的位置:首页 > 编程语言 > C语言/C++

C++中的左值和右值

2016-04-11 09:19 288 查看


左值和右值的定义

在C++中,可以放到赋值操作符=左边的是左值,可以放到赋值操作符右边的是右值。有些变量既可以当左值又可以当右值。进一步来讲,左值为Lvalue,其实L代表Location,表示在内存中可以寻址,可以给它赋值(常量const类型也可以寻址,但是不能赋值),Rvalue中的R代表Read,就是可以知道它的值。例如:

int a=3;

a在内存中有地址,而3没有,但是可以read到它的值。

3=4;

这个是错误的,因为3的内存中没有地址,不能当作左值。

下面这个语句不容易出错

a++=3;

这个语句编译通不过的,原因在于a++是先使用a的值,再给a加1。实现如下:

[cpp] view
plain copy

{

int tmp=a;

a=a+1;

return tmp;

}

a++是右值。

++a=3;

这个是正确的,++a的实现如下:

[cpp] view
plain copy

{

a=a+1;

return &a;

}

显然++a的效率高。


左值符号&和右值符号&&

左值的声明符号为&,右值的声明符号为&&。在C++中,临时对象不能作为左值,但是可以作为常量引用const &

[cpp] view
plain copy

#include<iostream>

void print_lvalue(int& i)//左值

{

std::cout << "Lvalue:" << i << std::endl;

}

void print_rvalue(int&& i)//右值

{

std::cout << "Rvalue:" << i << std::endl;

}

int main()

{

int i = 0;

print_lvalue(i);

print_rvalue(1);

//print_lvalue(1)会出错

//print_lvalue(const int& i)可以使用print_lvalue(1)

return 0;

}

int&&可以理解为右值引用,其作用是将变量绑定到一个临时变量上,一般是函数返回值。
如:
int somemethod()
{
int a = 10;
return a;
}
int&& b = some_method();
这样可以减少函数返回操作并且赋值操作时new、delete、copy操作,提高效率。特别是当返回类型比较庞大的时候,作用明显。

int&&作为形参的情况,作用类似。


C++11中的move

有时候我们希望把左值当作右值来使用,例如一个变量的值,不再使用了,希望把它的值转移出去,C++11中的std::move就为我们提供了将左值引用转为右值引用的方法。

[cpp] view
plain copy

#include<iostream>

void print_value(int& i)//左值

{

std::cout << "Lvalue:" << i << std::endl;

}

void print_value(int&& i)//右值

{

std::cout << "Rvalue:" << i << std::endl;

}

int main()

{

int i = 10;

print_value(i);

print_value(std::move(i));

return 0;

}

最长用的交换函数

[cpp] view
plain copy

void swap(T& a, T& b)

{

T tmp = std::move(a);

a = std::move(b);

b = std::move(tmp);

}

避免了3次拷贝。

精确值传递

std::forward主要用于模板编程中,值传递的问题。可以推测参数是左值引用还是右值引用,精确传递值。参考这里:
http://blog.csdn.net/zwvista/article/details/6848582
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: