简体   繁体   English

什么是 EMC++ 中提到的“源 object 是左值”场景,其中移动语义没有提供效率增益

[英]What is the “source object is lvalue” scenario, mentioned in EMC++, where move semantics offer no efficiency gain

Item 29 from Effective Modern C++, Scott Meyers lists three scenarios where move semantics don't improve code's performance, Effective Modern C++ 中的第 29 项,Scott Meyers 列出了移动语义不会提高代码性能的三种场景,

[…] move semantics do you no good: […] 移动语义对你没有好处:

  • No move operations: The object to be moved from fails to offer move operations […]无移动操作:要从中移动的 object 无法提供移动操作 […]
  • 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 .移动不可用:上下文 […] 需要一个不发出异常的移动操作,但该操作未声明为noexcept

which are all clearly explained in the preceding pages, and then adds another one前面几页都解释清楚了,然后再加一个

[…] another scenario where move semantics offers no efficiency gain: […] 移动语义没有提供效率增益的另一种情况:

  • Source object is lvalue: With very few exceptions (see eg Item 25) only rvalues may be used as the source of a move operation.源 object 是左值:除了极少数例外(参见例如条款 25),只有右值可以用作移动操作的源。

(Item 25 is titled Use std::move on rvalue references and std::forward on universal references , but I don't see how it is related to the bullet point that cross-references it.) (第 25 项的标题为Use std::move on rvalue references 和std::forward on Universal references ,但我看不出它与交叉引用它的项目符号点有何关系。)

After this, the text essentially goes back to summarizing the item, with no further reference to that fourth bullet point.在此之后,文本基本上回到了对该项目的总结,没有进一步提及第四个要点。

What does that bullet point refer to?那个要点是指什么?

As far as I understand move semantics, even if I want to move from an lvalue, say x , I still need to cast it to an rvalue via std::move(x) (or an equivalent static_cast ), so I'm technically still moving from an rvalue (specifically an xvalue in this case), not an lvalue.据我了解移动语义,即使我想从左值移动,比如x ,我仍然需要通过std::move(x) (或等效的static_cast )将它转换为右值,所以我在技术上仍然从右值(在这种情况下特别是 xvalue)移动,而不是左值。

So I'd be tempted to say that an lvalue cannot be the source object of a move operation.所以我很想说左值不能是移动操作的源 object。

What am I missing about this topic?我对这个话题缺少什么?

The term lvalue refers to somehow “named” values, ie, entities having multiple references.术语左值是指以某种方式“命名”的值,即具有多个引用的实体。 Move semantics don't really apply to them as you shouldn't “steal” the representation of something which may be referred to elsewhere.移动语义并不真正适用于它们,因为您不应该“窃取”可能在其他地方引用的某些东西的表示。 That is, if the source object is an lvalue you simply never move, So.也就是说,如果源 object 是一个左值,你就永远不会移动,所以。 move construction doesn't provide a benefit here, In fact, lvalues don't bind willingly to rvalue references - you'd beed to force that binding. move 构造在这里没有提供任何好处,事实上,左值不会自愿绑定到右值引用 - 你需要强制绑定。 eg,, by using std::move() .例如,通过使用std::move()

Essentially, your point is entirely correct: an lvalue cannot be the source of a move operation - and hence move operations don't provide a benefit where lvalues are involved.从本质上讲,您的观点是完全正确的:左值不能成为移动操作的来源 - 因此移动操作在涉及左值时不会提供好处。

As an example: You have a class T with a move constructor.例如:您有一个带有移动构造函数的 class T。 You have a function returning an object of type T, and you try to make it faster by returning in r-value.您有一个 function 返回一个 T 类型的 object,并且您尝试通过返回 r 值来使其更快。 Now if you start with现在如果你开始

T x;
x.a = ...;
x.b = ...;
x.c = ...;
return x;

then an object x will be constructed, a new unnamed object will be created by the return statement, then x is destructed, then the return value is moved.然后将构造一个 object x,通过 return 语句创建一个新的未命名的 object,然后破坏 x,然后移动返回值。 And eventually the caller will call the destructor for the moved result.最终调用者将为移动的结果调用析构函数。 So you have two constructors, two destructors, no savings.所以你有两个构造函数,两个析构函数,没有节省。

If you start with如果你从

T x(a, b, c);
return x;

then you have the same problem, two constructors and destructors, no savings.那么你有同样的问题,两个构造函数和析构函数,没有节省。 To actually save anything, you need to write要实际保存任何内容,您需要编写

return T(a, b, c);

or return the return value of another function returning an object.或返回另一个 function 的返回值,返回一个 object。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM