从函数返回值以避免复制时使用std :: move() [英] Using std::move() when returning a value from a function to avoid to copy

查看:119
本文介绍了从函数返回值以避免复制时使用std :: move()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑支持默认移动语义的T类型。还考虑下面的函数:

Consider a type T supporting the default move semantics. Also consider the function below:

T f() {
   T t;
   return t;
}

T o = f();

在旧的C ++ 03中,某些非最佳编译器可能会两次调用复制构造函数,一个

In the old C++03, some non-optimal compilers might call the copy constructor twice, one for the "return object" and one for o.

在c ++ 11中,因为<$ c $是一个返回对象,另一个是 o f()中的c> t 是一个左值,这些编译器可能会像以前一样调用一次拷贝构造函数,然后为o。

In c++11, since t inside f() is an lvalue, those compilers might call the copy constructor one time as before, and then call the move constructor for o.

是否正确地声明避免第一个额外副本的唯一方法是移动 t 当返回时?

Is it correct to state that the only way to avoid the first "extra copy" is to move t when returning?

T f() {
   T t;
   return std::move(t);
}


推荐答案

否。每当 return 语句中的局部变量有资格进行复制省略时,它会绑定到右值re­ fe­ rence,因此 return t; 在您的示例中与 return std :: move(t); 相同,即符合条件的构造函数。

No. Whenever a local variable in a return statement is eligible for copy elision, it binds to an rvalue re­fe­rence, and thus return t; is identical to return std::move(t); in your example with respect to which constructors are eligible.

但是请注意,返回std :: move(t); 防止编译器执行复制省略,而返回t ;不需要,因此后者是首选样式。 [感谢@Johannes提供的校正。]如果发生复制省略,则是否使用移动构造的问题将成为讨论的重点。

Note however that return std::move(t); prevents the compiler from exercising copy elision, while return t; does not, and thus the latter is the preferred style. [Thanks to @Johannes for the cor­rect­ion.] If copy elision happens, the question of whether or not move construction is used becomes a moot point.

请参见在标准中为12.8(31,32)。

See 12.8(31, 32) in the standard.

还请注意,如果 T 具有可访问的副本,但删除move构造函数,然后返回t; 将不会编译,因为必须首先考虑move构造函数;您必须说出 return static_cast< T&>(t); 的效果才能使它起作用:

Note also that if T has an accessible copy- but a deleted move-constructor, then return t; will not com­pile, because the move constructor must be considered first; you'd have to say something to the ef­fect of return static_cast<T&>(t); to make it work:

T f()
{
    T t;
    return t;                 // most likely elided entirely
    return std::move(t);      // uses T::T(T &&) if defined; error if deleted or inaccessible
    return static_cast<T&>(t) // uses T::T(T const &)
}

这篇关于从函数返回值以避免复制时使用std :: move()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆