gpt4 book ai didi

c++ - 左值何时在 C++ 中 move 而不是复制?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:34 25 4
gpt4 key购买 nike

鉴于以下情况:

Foo getFoo()
{
Foo result = doSomeWork();
return result;
}
  • C++ 是否保证 result 会被 move ,而不是被复制?或者换句话说,编写 return std::move(result) 是多余的吗?

  • 在没有显式 std::move 强制转换的情况下,是否有任何(其他)标准规定将静默 move 而不是复制左值的情况?

注意事项:

  • 假设 Foo 是可 move 构造的。

  • 忽略复制/move 省略,这可能另外适用。

最佳答案

  1. 尽管 move 可能会被省略,但是是的。如果 move 构造函数可用,则永远不会发生复制。为了清楚起见,我将再次引用该段落。 [class.copy]/32:

    When the criteria for elision of a copy/move operation are met, but not for an exception-declaration, and the object to be copied is designated by an lvalue, or when the expression in a return statement is a (possibly parenthesized) id-expression that names an object with automatic storage duration declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If the first overload resolution fails or was not performed, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. — end note ]

    应用 std::move 不是多余的,但实际上防止执行复制省略,[class.copy]/31:

    — in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object [..]

  2. 是的,一种情况 - 我再次假设您的意思是如果不执行复制省略,则 move 完成(如果左值被 move ,复制省略必须适用,s.a.)。
    考虑一下:

    A a;
    throw a;

    满足条件:

    — in a throw-expression, when the operand is the name of a non-volatile automatic object (other than a function or catch-clause parameter) whose scope does not extend beyond the end of the innermost enclosing try-block (if there is one), the copy/move operation from the operand to the exception object (15.1) can be omitted by constructing the automatic object directly into the exception object

    Demo .
    这是 move 左值而不是复制左值的唯一其他情况;复制省略的其他两种情况仅包括未绑定(bind)到引用的临时对象(因此必须由 prvalues 指定)和异常声明,这在这里没有意义,因为它涵盖了我们看不到的异常对象。

关于c++ - 左值何时在 C++ 中 move 而不是复制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27695528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com