std::string s = "y";
s = "x" + std::move(s) + "x";
Send(std::move(s));
微软的STL实现会检查这一点,但标准要求吗?
相对于插入+追加或使用两个变量的方法,这看起来更加简洁。
注意:我知道我可以使用Send(std::move("x" + std::move(s) + "x"))
,但实际代码并不简单。
这里没有自己移动的操作。自己移动是指像这样的东西:
s = std::move(s);
这意味着
s.operator=(std::move(s));
换句话说,当调用operator=
时,this
指向与参数相同的字符串。
在您的代码中,"x" + std::move(s)
将首先被评估,它返回一个std::string
prvalue。换句话说,并不是对s
的引用,尽管连接可能会从s
中“窃取”缓冲区。然后评估第二个+
,并返回另一个prvalue。最后,调用operator=
。此时,右侧的prvalue必须具体化,因为它绑定到operator=
的rvalue引用参数。因此,我们只有s
从临时对象被赋值的情况,其中可能已经从s
中窃取了缓冲区。但无论如何:s
是一个标准库类型的对象,这意味着它处于“有效但未指定状态”。由于s
处于有效状态,并且与RHS不是同一对象,因此没有问题。operator+
不会返回其参数的 rvalue reference,而是返回一个 prvalue,该 prvalue 在您所查看的具体实现中由其 rvalue reference 参数初始化。请注意返回类型不是 rvalue reference。 - Brian Biv = std::move(v);
和 v=v;
都是无操作语句。这是确保自我赋值不会引起任何问题的基础之一。通常情况下,它不需要是无操作语句,但我还没有找到一个例子证明它不是(除非出于某些原因进行了一些副作用)。 - ALX23zv = std::move(v)
对于某些(大多数?)实现来说会清除向量。我认为这是自然结果,当你考虑“性能”时(最小化操作和检查的数量)。而且这不是“int”的行为©。 - alfC
"x" + std::move(s) + "x"
中,std::move
的目的是什么? - Some programmer dudestd::move
。除非有确凿证据表明性能成为问题,否则应选择可读性优化。我还会争辩说,这种方式在任何情况下都不会“看起来更清晰”。 - DevSolarstd::move("x" + std::move(s) + "x")
。这里两次使用std::move
都是过早的悲观优化,而且是不必要的,因为中间结果都是临时的。 - Eljaymove
时,第一个调用的是operator+(const char*, string&&)
而不是operator+(const char*, const string&)
。 - OwnageIsMagic