将文字常量分配给右值参考时会发生什么?

时间:2015-10-12 16:22:04

标签: c++ move-semantics

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

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的值不可修改(在上面片段的最后两行中有点迂实地表示)。

所以我的问题是,到底发生了什么? C ++如何知道不修改常量文字5的值,同时保持xref足够的身份,以便知道它已被赋值更改为10。当一个新变量绑定到一个常量字面值时,它是在赋值给xref时创建的吗?这个问题从未出现在C ++ 03中,因为只有const引用可以绑定到rvalues。

2 个答案:

答案 0 :(得分:8)

int&& xref = 5;

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

作业

xref = 10;

改变静止生活的价值。

答案 1 :(得分:6)

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

就生命而言,这就像你写的const int& x = 5一样;只有,在那里,您使用自动创建的临时对象的事实被屏蔽,因为const阻止您通过突变来证明它。

  

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