本节介绍c++左值和右值的相关知识。网上有很多种关于左值右值的定义,例如左值是有内存地址的,右值没有等等。我们可以不去坚持找到明确的定义,我们仅需要知道左值和右值是什么即可。
#include <iostream>
#include <string>
//右值也可以是函数的返回值,例如
int GetValue()
{
return 10; //返回的是右值,返回的是一个临时值
}
void SetValue(int& value)
{
}
//void PrintName(std::string name)
//{
//
//}
//void PrintName(std::string& name)
//{
//
//}
//void PrintName(const std::string& name)
//{
//
//}
//传递的参数是右值引用
void PrintName(std::string&& name)
{
}
int main() {
/*
i在内存中有地址,是左值,10在内存中没有地址是右值,可以给左值赋值,但不能赋值给右值
如 15 = i
*/
int i = 10;
//GetValue() = 12; //因为GetValue()返回的是右值,所以不能给其赋值
//不能将右值赋值给左值引用,左值引用只能是左值
SetValue(i); //可以将左值赋值给左值引用
//SetValue(11); //不能将右值赋值给左值引用
//int& j = 11; //不能将右值赋值给左值引用
const int& j = 11; //这样是可以的,左值引用可以兼容最值和右值
//const int& j = 11;在编译器的操作实际上会创建一个临时的左值给11
std::string firstName = "p"; //"p"是右值
std::string lastName = "cp"; //"cp"是右值
std::string myName = firstName + lastName;
//PrintName(firstName + lastName); //可行,将右值赋值给左值
//如果PrintName传递的是左值引用,则PrintName(firstName + lastName);不可行
// PrintName(firstName + lastName); 不可行,因为PrintName参数是左值引用
//如果PrintName参数是常量的左值引用,则兼容左值右值
//PrintName(firstName); //可行,常量的参数,兼容左值右值
//右值引用 std::string&& name
//PrintName(firstName); //不可行,报错无法将右值引用绑定在左值
PrintName(firstName+lastName); //可行,将右值引用绑定右值是可行的
//右值引用的主要优势在于优化,因为传入的是一个临时变量,不用担心变量的生命周期,同时可以任意使用临时变量,因为临时变量仅在当前用的地方使用
}