原本只是想搜索下emplace_back和push_back用法的区别,然后就越挖越深,底层的原理现在还不能总结的好就不写了,这篇文章就先记录下左值、左值引用,右值、右值引用。
一、左值和右值
浅显的理解就是“=”号左边的为左值,右边的为右值;严格点划分就是左值可以取地址,右值不可取地址
eg:int a=24;
显然a是左值,我们可以对其取地址操作(即&a);24就是右值,不可去地址。
二、左值引用和右值引用
1、形式
左值引用为 T &
右值引用为 T &&
2、定义
显然左值引用得引用一个左值,那左值引用就得用左值来初始化
int a=24;
int &left=a;//正确,a是左值,在之后就可以简单的把&left视作a
int &left=24;//错误,24是一个右值
同理,右值引用就需要右值来初始化
int a=24;
int &&right=a;//错误,a是左值
int &&right=24;//正确,24是一个右值,在之后就可以简单的把&&right视作24
既然可以int a=24,那么有个大胆的想法
left=right;//在定义之后,就可以这么玩了
左值引用和右值引用容易出错就是在他俩作为函数的形参时,调用函数的实参类型要保持一致
void fun(int &left,int &&right)//在函数里面,可以把两个形参当做普通变量玩
{
std::cout<<left<<"; "<<right<<std::endl;//输出24;10,即实参传递过来的
std::cout<<&left<<"; "<<&right<<std::endl;//输出left和right的地址:0x61fe18; 0x61fe1c(这里的输出结果每个人可能不一致)
left=8; //将left重新赋值
std::cout<<left<<std::endl;; //输出8
left=right; //将left重新赋值为right的值
std::cout<<left<<std::endl; //输出10
int b = right;
std::cout<<b <<"; "<<right<<std::endl; //输出10;10
right=2;
std::cout<right<<std::endl; //输出2,这么玩也OK
}
int main()
{
int a=24;
fun(a,10);
/* 测试两个典型错误,调用函数时一定要注意传递参数的类型*/
fun(a,a);//报错:无法将左值绑定到右值
fun(24,24);//报错:非常量引用的初始值必须为左值
}
就先记录到这,之后有新的理解再继续更新。