我无法确定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;
}
不仅可以移动返回值,而且可以省略移动本身。