非常量引用初始化必须为左值
当引用的初始式是一个左值(是一个对象,你可以取得它的地址),其初始化就是非常简单的事情。对"普通"T&的初始式必须是一个类型T的左值。
 对一个const T&的初始式不必是一个左值,甚至可以不是类型T;在这种情况下:
 1 首先,如果需要将应用到T的隐式类型转换
 2 而后将结果存入一个类型T的临时变量
 3 最后,将此临时变量用做初始式的值
考虑
 double& dr = 1; //错误:要求左值
 const double& cdr = 1; //ok
对后一个初始化的解释是
 double temp = double(1); //首先建立一个具有正确值的临时变量
 const double& cdr = temp; //而后用这个临时变量作为cdr的初始式
这种保存引用初始式的临时变量将一直存在,直到这个引用的作用域结束
以上来自《The C++ programming language》
我们自己也可以看个例子:
 int a = 2;
 double& b = a;//错误 ,要求是double类型的
 error:invalid initialization of non-const reference of type ‘double&’ from an rvalue of type ‘double’
 从书中和自己测试的来看非常量引用初始化左值必须为一个相同类型的左值,但是如果加上const就像书中所说不需要是左值或者说不需要是相同类型
====================================
 对于书中说的左值做个详细的介绍如下:
 区分左值与右值:
   C++ 11中引入的一个非常重要的概念就是右值引用。理解右值引用是学习“移动语义”(move semantics)的基础。而要理解右值引用,就必须先区分左值与右值。
   对左值和右值的一个最常见的误解是:等号左边的就是左值,等号右边的就是右值。
   左值和右值都是针对表达式而言的,左值是指表达式结束后依然存在的持久对象,右值是指表达式结束时就不再存在的临时对象。一个区分左值与右值的便捷方法是:看能不能对表达式取地址,如果能,则为左值,否则为右值。下面给出一些例子来进行说明。 
int a = 10;
 int b = 20;
 int* pFlag = &a;
 vector<int> vctTemp;
 vctTemp.push_back(1);
 string str1 = "hello ";
 string str2 = “world”;
 const int &m = 1;
 请问,a,b, a+b, a++, ++a, pFlag, *pFlag, vctTemp[0], 100, string(“hello”), str1, str1+str2, m分别是左值还是右值?
 
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号