来自 Effective Modern C++ 的第 29 项,Scott Meyers 列出了 move 语义不会提高代码性能的三种情况,
[…] move semantics do you no good:
- No move operations: The object to be moved from fails to offer move operations […]
- Move not faster: […] move operations that are no faster than its copy operations.
- Move not usable: The context […] requires a move operation that emits no exceptions, but that operation isn't declared
noexcept
.
前几页都解释清楚了,再补充一个
[…] another scenario where move semantics offers no efficiency gain:
- Source object is lvalue: With very few exceptions (see e.g. Item 25) only rvalues may be used as the source of a move operation.
(条目 25 的标题是在右值引用上使用 std::move
和在通用引用上使用 std::forward
,但我不看不出它与交叉引用它的要点有什么关系。)
在此之后,文本实质上回到了对该项目的总结,没有进一步提及第四个要点。
那个要点指的是什么?
就我理解的 move 语义而言,即使我想从左值 move ,比如说 x
,我仍然需要通过 std::move(x )
(或等效的 static_cast
),所以我在技术上仍然从右值(在这种情况下特别是 xvalue)而不是左值 move 。
所以我很想说左值不能是 move 操作的源对象。
关于这个话题我错过了什么?
最佳答案
术语 lvalue 以某种方式指代“命名”值,即具有多个引用的实体。 move 语义并不真正适用于它们,因为你不应该“窃取”可能在别处引用的东西的表示。也就是说,如果源对象是一个左值,你根本就不会 move !因此, move 构造在这里没有任何好处。事实上,左值不会自愿绑定(bind)到右值引用 - 你必须强制绑定(bind),例如,通过使用 std::move()
。
从本质上讲,您的观点是完全正确的:左值不能作为 move 操作的来源 - 因此 move 操作不会在涉及左值的情况下提供好处。
关于c++ - EMC++ 中提到的 "source object is lvalue"场景是什么,其中 move 语义没有提供效率增益,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65442298/