【问题标题】:What happens when you assign a literal constant to an rvalue reference?当您将文字常量分配给右值引用时会发生什么?
【发布时间】:2016-01-10 04:59:27
【问题描述】:

这无疑是一个挑剔的问题,主要是出于好奇。假设我们有以下内容:

int x = 5;
int&& xref = std::move(x);
std::cout << "Before assignment x: " << x << std::endl;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment x: " << x << std::endl;
std::cout << "After assignment xref: " << xref << std::endl;

预期的输出是:

// Before assignment x: 5
// Before assignment xref: 5
// After assignment x: 10
// After assignment xref: 10

这是有道理的。 std::movex 转换为一个xvalue,并允许我们将其内存位置绑定到xref 并相应地修改其内容。现在假设我们有以下内容:

int&& xref = 5;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment xref: " << xref << std::endl;

int x = 5;
std::cout << "After assignment x: " << x << std::endl;

输出很直观:

// Before assignment xref: 5
// After assignment xref: 10
// After assignment x: 5

这在整体上是有道理的。我们希望能够将常量文字5 绑定到xref,因为5 是prvalue。我们还期望xref 是可变的。我们进一步期望常量字面量5 的值是不可修改的(如上面sn-p 的最后两行所示有点迂腐)。

所以我的问题是,这里到底发生了什么? C++ 如何知道不修改常量文字 5 的值,但仍为 xref 保持足够的标识,以知道它已通过赋值更改为 10。当绑定到常量文字时,是否在分配给 xref 时创建了一个新变量?这个问题在 C++03 中从未出现过,因为只有 const 引用可以绑定到右值。

【问题讨论】:

    标签: c++ move-semantics


    【解决方案1】:
    int&& xref = 5;
    

    ... 创建一个临时的,初始化为 5,其生命周期延长到块的末尾。

    任务

    xref = 10;
    

    更改仍然活着的临时对象的值。

    【讨论】:

      【解决方案2】:

      构造一个临时的,从字面量的值初始化,它的持续时间与引用一样长。你可以用这个对象做你喜欢的事情。

      就生命周期而言,这与您编写const int&amp; x = 5 相同;只是,在那里,您正在使用自动创建的临时对象这一事实被掩盖了,因为const 阻止您通过突变来证明它。

      [C++14: 8.5.3/5]: [..] 如果T1 是非类类型,则会创建一个临时类型为“cv1 T1”并复制-从初始化表达式初始化(​​8.5)。然后将引用绑定到临时文件。 [..]

      【讨论】:

      • 谢谢。这回答了我的问题以及我可能遇到的每一个后续问题。
      • @Klam:Lightness Industries 的所有服务部分。
      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      • 2017-09-15
      相关资源
      最近更新 更多