【问题标题】:Why a rvalue cannot be used to initialize a lvalue reference?为什么不能使用右值来初始化左值引用?
【发布时间】:2018-03-16 07:29:29
【问题描述】:

const A& a = A()A&& a = A() 我可以,但为什么我不能A& a = A()

【问题讨论】:

  • 由于过去的一个可能不幸的决定,我想您可能会将仅出现在模板中的转发引用与右值引用混淆。它们共享相同的&& 语法,但它们是完全不同的东西。问题太模糊了。发布 minimal reproducible example 并包含 A&& a = A()
  • @JiveDadson 这个问题对我来说似乎很明显是关于右值引用,而不是转发引用。我回头看看在编辑之前是否可能不清楚,但不,在最初的版本中也很清楚。
  • @hvd +1。我很困惑为什么这个问题被认为是模糊的。如果有人认为它含糊不清,你能告诉我为什么和在哪里吗?否则,将其搁置为不清楚但不告诉不清楚的地方是非常令人困惑的。
  • 基本原理是,对临时变量进行突变几乎没有意义,任何这样做的尝试都可能是编程错误,而不是深思熟虑的决定。虽然您有时确实想要改变一个临时值,但它通常是出于与改变左值完全不同的原因(存在右值引用以适应这些情况)。
  • @n.m.我认为这应该是一个答案。

标签: c++ rvalue-reference rvalue


【解决方案1】:

基本原理是突变一个临时的很少有意义。任何这样做的尝试都可能是一个编程错误,而不是一个深思熟虑的决定。

原型示例如下。假设允许绑定到非常量引用。

void foo(int& x, int& y); // sets x and y
int xx, yy;
foo(xx, yy); // xx and yy are set
// now make a small change...
void foo(long& x, long& y); // upgrade
int xx, yy; // forgot to change here 
foo(xx, yy); // silently breaks

虽然有时确实想要改变一个临时值,但它通常是出于与改变左值完全不同的原因。发明了右值引用来适应这些情况。

【讨论】:

  • 我试过你的例子,编译失败并出现错误invalid initialization of non-const reference of type ‘long int&’ from an rvalue of type ‘long int,我知道这是因为在我做第二个foo(xx, yy);时创建了一个临时变量。但我不太清楚你对// silently breaks 的意思,你能详细说明一下吗?谢谢!
  • @Eric 你读过我写的吗? 假设绑定到非常量引用是允许的。.
  • 对不起,我误解了你的意思。现在我明白了,如果允许绑定到非常量引用,foo 的功能将被静默破坏。谢谢!
【解决方案2】:

通过“初始化左值引用”,您指的是定义从那时起引用所引用的左值。
因此,左值引用将传播对右值“初始化”的任何访问。
IE。您会尝试访问像左值这样的右值表达式。
不可能在所有情况下都像左值一样访问右值。

这就是为什么。

【讨论】:

  • 我不认为这就是他的意思。这个问题太模糊了。
  • @JiveDadson 你可能是对的。我的印象是,整个(模糊的)问题只是基于对参考是什么的误解。在我看来,整个“它就是事物和事物本身”的想法并没有得到理解。我觉得虽然问题很模糊,但问题很明确。
【解决方案3】:

右值是暂时的——它很快就会消失。创建对此类对象的左值引用将导致灾难,因为该引用会很快成为对死对象的悬空引用。

【讨论】:

  • 那么为什么右值引用不会变得悬空呢?
  • @songyuanyao 绑定对prvalue的引用会延长prvalue的临时物化的生命周期
猜你喜欢
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 2018-11-05
  • 2016-06-09
  • 1970-01-01
相关资源
最近更新 更多