C++ 为了提高效率,在返回语句中应该使用std::move吗?

C++ 为了提高效率,在返回语句中应该使用std::move吗?,c++,c++11,move-semantics,C++,C++11,Move Semantics,我不知道下面代码中的std::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

我不知道下面代码中的std::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
}
下面是我用来测试它的代码:

Object<double> test(4);
Object<double> test2(test * 4);
std::cout << test2; // works fine
对象测试(4);
对象test2(test*4);
标准::cout
一个比另一个更有效吗?因为我假设将新对象移出而不是复制它会更快

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

通常,在返回临时变量或局部变量时,将自动使用移动语义。但是,在这种情况下,您并不是直接返回临时值,而是由
操作符*=
返回的左值引用。因为左值不会被移动,所以在本例中,您确实需要
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;
}
模板
对象对象::运算符*(常量F&rhs)常量
{
对象lhs(*此);
lhs*=rhs;
返回lhs;
}

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

不要返回
const
值,不要显式地
std::move
局部变量/临时变量,它会抑制(N)RVO。为什么不将
操作符*
写为
对象tmp(*this);tmp*=rhs;返回tmp?通过这种方式,编译器可以看到您返回一个局部变量,并在
返回时自动将其转换为右值。请看:我刚刚在没有
常量的情况下进行了测试,它不会改变这种情况,但从答案中我可以理解,当我返回
左值时,我需要
std::move
。另一方面,如果是和
rvalue
我不需要
std::move
。最后,如果我使用了一个临时变量,它会自动移出?我怀疑RVO会处理左值的情况,所以它应该是不可区分的(RVO甚至比move有一点优势)。但您的最后一个示例(局部变量)解决了所有问题+1@syam:我相当肯定,只有(直接)返回临时或局部自动变量时才允许省略。当然,我的编译器在返回左值时不会删除副本。还请建议返回一个非
常量
对象
,因为如果像
auto c=a*b
@Xeo:是的,我刚刚注意到了
常量
,并添加了一些关于不要这样做的建议。(我在测试中没有注意到这一点,因为该副本可以省略)。
Object<double> test(4);
Object<double> test2(test * 4);
std::cout << test2; // works fine
template<typename T> template <typename F> 
Object<T> Object<T>::operator*(const F& rhs) const 
{
    Object lhs(*this);
    lhs *= rhs;
    return lhs;
}