【问题标题】:Why don't xvalues bind to non-const lvalue references?为什么 xvalues 不绑定到非常量左值引用?
【发布时间】:2015-12-27 19:56:22
【问题描述】:

以下内容无法编译:

#include <iostream>
using namespace std;

int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }

int main() {
    g(f());
    return 0;
}

我很清楚为什么prvalues(未命名的临时变量)不绑定到非常量左值引用——修改它们没有意义,因为它们很快就会消失。但是为什么 xvalues 不绑定到非 const 左值引用?

如果函数返回int &amp;&amp;,则引用的对象不能是临时的,否则我们会得到一个悬空引用。因此,如果返回 int &amp;&amp;,在我的理解中,这是一个额外保证可以安全移出它的引用。

编辑:措辞更正:“值”绑定到“引用”,反之亦然。

第二次编辑:以下编译——我看不出概念上的区别,除了 y 现在是一个左值。然而它仍然引用 x。根据语言规范,我理解为什么这应该编译而上述内容不应该编译。但是,我不明白其背后的原因。为什么单纯的锯齿会改变图片?

#include <iostream>
using namespace std;

int x = 5;
int && f () { return std::move(x); }
int g(int & y) { return y; }

int main() {
    int && y = f(); // reference!
    g(y); // compiles

    // check that y indeed references x
    y = 7;
    std::cout << x << std::endl; // prints 7, of course
    return 0;
}

第三次编辑:简而言之,不允许背后的想法是什么

int && f() { ... }
int g (int & y) { ...}
g(f());

允许

int && f() { ... }
int g (int & y) { ...}
int & k (int && y) { return y; }
g(k(f()));

【问题讨论】:

  • re“不能是临时的”,考虑auto f( int&amp;&amp; x ) -&gt; int&amp;&amp; { return move(x); }
  • 请注意,给定 struct A { int x; };A().x 是一个 xvalue,每个 CWG DR 616
  • @Cheersandhth.-Alf 我认为(但如果我错了,请纠正我)OP 并不是说​​ xvalues 不可能引用临时变量,而是你的示例函数已经应该不能这样写,这是一个糟糕的函数定义,因为它允许返回即将悬空的引用。
  • 我认为“绑定到 xvalue”这个术语没有意义。值绑定到引用,这是语言中唯一存在的相关概念。
  • @hvd:这将使 OP 的推理循环。

标签: c++ c++11 rvalue-reference


【解决方案1】:

因为那样会弄得一团糟。

const 左值引用的全部意义在于它们是非临时对象的别名,这些对象的生命周期已经由其他方式管理。右值引用的引入——以及至关重要的std::move——专门用于创建一个新的引用“类”,其绑定表示引用对象很可能是“安全”的。

如果这些引用对象也能够绑定到一个简单的T&amp;,那么您将遇到大量模棱两可的转换错误,并且没有人会知道该怎么做。你可以给这样的转换一个较低的排名,但我觉得这仍然会非常令人困惑。

因此,您是在向后看。问问自己为什么xvalues 不绑定到非常量左值引用

【讨论】:

  • 我发帖的措辞是错误的。然而我还是不明白。我将尝试通过一个例子来扩展我的问题。
  • @JohnB:我的答案没有改变。
  • 我仍然不明白为什么不应该将一个说“它可以从我身边移开”的对象传递给只需要修改该对象的函数。
  • @JohnB:首先,您的示例与此不符。他们要么不绑定到您询问的int&amp;,要么他们说“离开我是安全的”。其次,考虑大局。这些规则必须共存于同一个世界并适应所有情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
相关资源
最近更新 更多