(1)左值可以放在赋值运算符的左边也可以放在赋值运算符的右边,右值只能放在赋值运算符的右边; (2)左值有名字,右值没有名字; (3)左值可以寻到对应地址,右值不存在地址。
(1)引用就是某一变量的一个别名,对引用的操作与对变量直接操作完全一样。 type &引用名 = 左值表达式;
(1)对右值(不能取地址)的引用叫右值引用: type &&引用名 = 右值表达式; (2)右值引用的意义: 1).右值引用绑定了右值,让临时右值的生命周期延长了(续命)。可以利用这个特点避免临时对象的拷贝构造和析构,优化性能。 2).常量左值引用也可以性能优化。输出的结果和右值引用相同,因为常量左值引用是一个“万能”的引用类型,可以接受左值、 右值、常量左值和常量右值。 const int& res = getVal(); //ok int&& res = getVal(); //ok int& res = gerVal(); //err
(1)右值引用: void f(int && param);//右值引用,不能传左参 (2)左值引用: void f(int & param);//左值引用,不能传右值 (3)通用引用: void f(T && param);//通用引用,类型为模板参数 如果被一个左值初始化,它就是一个左值;如果它被一个右值初始化,它就是一个右值,取决于它的初始化。
例子: template void f(T && param); int i = 10; f(i);//左值 f(10);//右值
(1)模板函数: template void f(T && param)//通用引用,如果T本身也是引用比如T&,或者T&&,那么原函数就会展开为:T& &&和T&& &&. void f2(T & param)//T本身就是T& T&&,那么展开为:T& &和T&& & (2)引用折叠规则: 1)X& &; X& &&; X&& &折叠为:X&(单个和单个,单个和双个) 2)X&& &&折叠为:X&&(双个和双个) (3)引用折叠解释通用引用:void f(T && param); int i = 0; f(i);//int& -> int& && -> int & f(10);//int->int &&