可以自行移动 std::string 吗?

Own*_*gic 5 c++ c++20

std::string s = "y";
s = "x" + std::move(s) + "x";
Send(std::move(s));
Run Code Online (Sandbox Code Playgroud)

Microsoft STL 实现会对此进行检查,但标准是否强制要求这样做?

它看起来比插入+附加或两个变量方法更干净。

注意:我知道我可以做到Send(std::move("x" + std::move(s) + "x")),但真正的代码并不那么简单。

Bri*_*ian 16

这里没有自我移动。自我移动是这样的:

s = std::move(s);
Run Code Online (Sandbox Code Playgroud)

意思是

s.operator=(std::move(s));
Run Code Online (Sandbox Code Playgroud)

换句话说,当operator=被调用时,this指向与参数相同的字符串。

在您的代码中,"x" + std::move(s)将首先求值,并返回std::string纯右值。换句话说,不是对 的引用s,尽管串联可能会从 中“窃取”缓冲区s。然后+计算第二个值,并返回另一个纯右值。最后,operator=被召唤。此时,右侧的纯右值必须被具体化,因为它绑定到 的右值引用参数operator=。因此,我们所拥有的只是s从一个临时对象中分配的,该对象可能窃取了s的缓冲区。但没关系:s是标准库类型的对象,这意味着它处于“有效但未指定的状态”。由于s处于有效状态,并且与 RHS 不是同一对象,因此没有问题。

  • @OwnageIsMagic `operator+` 不会返回对其参数的右值引用。它返回一个纯右值,在您正在查看的特定实现的情况下,该纯右值是从其右值引用参数初始化的。请注意,返回类型不是右值引用。 (2认同)