9

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

第一:随着移动:

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
}

第二:没有移动

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

结果 在第一种情况下,我们以移动构造函数结束,而在第二种情况下,我们以复制构造函数结束。

无论哪种情况,代码都会编译。

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

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

4

1 回答 1

15

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

std::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;
}

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

于 2013-05-17T09:53:25.793 回答