应该在返回语句中使用std::move来提高效率吗?

Should std::move be used in return-statements for effeciency?

本文关键字:move 提高效率 std 返回 语句      更新时间:2023-10-16

我无法确定std::move在以下代码中是否有任何好处或它是完全错误的?类Object定义了Move和Copy构造函数。

First: With Move:

template<typename T> template <typename F> 
const Object<T> Object<T>::operator*(const F& rhs) const 
{
    return std::move(Object(*this) *= rhs);  // We end in move constructor
}

Second: Without Move:

template<typename T> template <typename F> 
const Object<T> Object<T>::operator*(const F& rhs) const 
{
    return Object(*this) *= rhs; // We end in copy constructor
}

*=操作符定义为:

template<typename T> template<typename F>  
Object<T>& Object<T>::operator*=(const F& rhs) 
{
    for(int i = 0; i < dimension ; i++)
    {
        _inner[i] *= rhs;
    }
    return *this;
}
下面是我用来测试它的代码:
Object<double> test(4);
Object<double> test2(test * 4);
std::cout << test2; // works fine
结果

第一个以move构造函数结束,第二个以复制构造函数结束。

在这两种情况下,代码都会编译。

是否一个比另一个更有效,因为我认为将新对象移出而不是复制它更快?

附加信息:我使用以下编译器:g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3

是否一个比另一个更有效,因为我认为将新对象移出而不是复制它更快?

是的,在这里使用std::move将更有效,假设对象具有比复制更有效的移动语义。

通常,当返回临时变量或局部变量时,会自动使用move语义。然而,在这种情况下,您不是直接返回临时的,而是由operator*=返回的左值引用。由于左值不会被移动,所以在本例中需要std::move将其转换为右值

然而,你不应该返回const值,因为这会阻止返回值被用于移动初始化(或移动赋值)另一个对象。您的示例将通过复制返回值来初始化test2,尽管该复制可能被省略。

或者,您可以使用一个局部变量来实现它:

template<typename T> template <typename F> 
Object<T> Object<T>::operator*(const F& rhs) const 
{
    Object lhs(*this);
    lhs *= rhs;
    return lhs;
}

不仅可以移动返回值,而且可以省略移动本身。