C++ 从右值初始化非常量引用

C++ 从右值初始化非常量引用,c++,c++11,visual-c++,C++,C++11,Visual C++,引用变量是一个别名,也就是一个值的别名,那么当returnByValue返回的值是右值时,案例I如何没有错误?案例II如何有编译错误?引用背后的基本思想是左值引用绑定到左值,右值引用绑定到右值;从此,这样绑定的引用将引用它绑定到的值 但是,C++对这个规则有一个例外,允许const LValk引用也绑定到rVals。这样做的原因主要是方便:它允许使用临时变量调用具有常量左值引用参数的函数,而不仅仅是使用左值: int returnByValue() { return 5; } int

引用变量是一个别名,也就是一个值的别名,那么当returnByValue返回的值是右值时,案例I如何没有错误?案例II如何有编译错误?

引用背后的基本思想是左值引用绑定到左值,右值引用绑定到右值;从此,这样绑定的引用将引用它绑定到的值

但是,C++对这个规则有一个例外,允许const LValk引用也绑定到rVals。这样做的原因主要是方便:它允许使用临时变量调用具有常量左值引用参数的函数,而不仅仅是使用左值:

int returnByValue()
{
    return 5;
}

int main()
{
    const int &cref = returnByValue(); // case I
    int &ref = returnByValue(); // case II -- compilation error
    return 0;
}
特别喜欢const ref参数的函数是复制构造函数和复制赋值运算符;如果这些只能在左值上调用,那么代码中需要更多的样板文件


此异常仅授予const引用,因为具有此类参数的函数不会修改参数,而只读取参数(如果愿意)。相比之下,右值引用不允许绑定到可变的左值引用,因为我们希望通过此类引用修改值,修改立即被破坏的内容几乎肯定是编程错误。但如果您确实需要,您可以编写一个用户定义的右值到左值的转换。

您的假设是错误的。引用不是变量的别名。它是值的别名。是的,值的别名已存在变量的另一个名称传递相同的信息。“已存在变量的另一个名称”传递相同的信息不,它不;它表达了一种微妙的不同的、不正确的说法。@VishvajeetT:这只是一种语言规则,它说常量左值引用可以绑定到右值。这样做的原因是,它方便地允许调用不使用临时值修改其参数的函数。我不理解您的问题标题:这个问题的哪一部分是关于非常量引用的?
void do_something(const ExpensiveType&);  // expects lvalue?

ExpensiveType make_one();

// ...

do_something(make_one());  // call with rvalue is OK, too!