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

Kla*_*lam 11 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;
Run Code Online (Sandbox Code Playgroud)

预期的输出是:

// Before assignment x: 5
// Before assignment xref: 5
// After assignment x: 10
// After assignment xref: 10
Run Code Online (Sandbox Code Playgroud)

这是有道理的. std::move转换x为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;
Run Code Online (Sandbox Code Playgroud)

输出直观:

// Before assignment xref: 5
// After assignment xref: 10
// After assignment x: 5
Run Code Online (Sandbox Code Playgroud)

这使整体意义重大.我们希望能够将常量文字绑定5xref因为5是一个prvalue.我们也期望这xref是可变的.我们进一步期望常量字面值5不可修改(在上面代码片段的最后两行中有点迂腐).

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

Che*_*Alf 8

int&& xref = 5;
Run Code Online (Sandbox Code Playgroud)

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

分配

xref = 10;
Run Code Online (Sandbox Code Playgroud)

改变了仍然生活的临时价值.


Lig*_*ica 6

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

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

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