为什么不能将非const的左值引用绑定到prvalue?

17
出于某种原因,我没有找到这个确切的问题。为什么允许将rvalue绑定到const lvalue引用,而不使用const则不可能呢?
我确实理解rvalue的生命周期在某种程度上得到了延长(在第一种情况下),但如果是这样的话,为什么编译器会禁止修改那个不再是临时对象的'rvalue'呢?
例如,考虑以下代码:
int main(){
   int &i = 3; //produces error
   const int &j = 3; //compiles
   return 1;
}

2
问题毫无意义。rvalue 不能被绑定。只有引用可以绑定到任何东西。 - SergeyA
14
@SergeyA,你知道提问者的意思。你可以进行编辑以改进它的表达。 - Gab是好人
1
哈哈哈哈,他自己就像一个编译器一样表现出来。 - polvoazul
3个回答

6

您可能会发现以下文章有用:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

我可能完全错误地理解了这个问题,但是这是我的理解方式。rvalue是常量,它无法改变。您无法更改整数5,这是事实。因此,当您绑定引用时,lvalue将必须是const。否则,您的编译器将抛出错误:

obj & a1 = bar();

invalid initialization of non-const reference of type ‘obj&from an rvalue of type ‘obj’

使用g++

安全地将rvalue绑定到lvalue的唯一方法是将lvalue标记为const,或者使用可变的rvalue引用&&(在C++11中引入?)。

struct obj {
};

obj bar() {
    obj x;
    return x;
}

int main() {
const obj & a1 = bar();
obj && a2 = bar();
return 0;
};

1
我理解你的思路,但是在将rvalue绑定到lvalue后,你实际上给了它一个名称,并延长了其生命周期,超出了当前行。如果我们现在暂时不考虑rvalue引用,我只谈论rvalue转为const lvalue引用的情况。所以我的问题仍然是相同的:为什么需要“const lvalue引用”的要求?为什么不能只使用“lvalue引用”? - Eliran Abdoo

2

如果您询问的是关于IT技术方面的问题:

void f(const int&);
f(1);

对比

void g(int&);
g(1);

答案在于考虑如果g是这样的会发生什么:
void g(int& r) {
    ++r;
}

1
也许一个更简单的例子,int main(){ int &i=3; //产生错误 const int&j =3; //编译通过 return 1; } - Eliran Abdoo
@GoldenSpecOps - 如果在初始化后添加 ++i;,你会看到为什么它不被允许;如果它一开始是 int j = 1; int&i = j; ++i;,那就没问题了。 - Pete Becker

0

r-value 的名称来自右值:大致意思是那些位于 x=y 这种语句的右侧的东西。就像:它可以被读取,但可能不适合被写入。例如,数字文字可以在右侧 (a=3),但没有意义放在左侧 (3=a)

基于这个推理,我认为允许对 r-value 进行 const l-value 引用是合理的,但不允许进行非 const 引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接