【问题标题】:Pass by value or rvalue-ref按值或右值引用传递
【发布时间】:2013-06-27 13:03:36
【问题描述】:

对于启用移动的课程,这两者之间有区别吗?

struct Foo {
typedef std::vector<std::string> Vectype;
Vectype m_vec;
//this or
void bar(Vectype&& vec)
{
   m_vec = std::move(vec);
}
//that
void bar(Vectype vec)
{
    m_vec = std::move(vec);
}
};
int main()
{
   Vectype myvec{"alpha","beta","gamma"};
   Foo fool; 
   fool.bar(std::move(myvec));
}

我的理解是,如果你使用左值myvec,你还需要引入const Vectype& 版本的Foo::bar(),因为Vectype&amp;&amp; 不会绑定。除此之外,在右值的情况下,Foo::bar(Vectype) 将使用移动构造函数构造向量,或者更好地忽略所有副本,因为 vec 是一个右值(会吗?)。那么是否有一个令人信服的理由不喜欢通过值声明而不是左值和右值重载? (考虑到无论如何我都需要将向量复制到成员变量中。)

【问题讨论】:

  • 在任何迂腐之前,我都知道重载是模棱两可的。

标签: c++ c++11 rvalue-reference


【解决方案1】:

按值传递版本允许使用左值参数并对其进行复制。不能使用左值参数调用右值引用版本。

当你根本不需要更改或复制参数时使用const Type&amp;,当你想要一个可修改的值但不关心你如何得到它时使用传递值,并使用Type&amp;Type&amp;&amp; 重载,当您希望根据上下文发生稍微不同的事情时。

【讨论】:

    【解决方案2】:

    传值函数就足够了(并且等效),只要参数类型具有有效的移动构造函数,在这种情况下std::vector 是正确的。

    否则,与使用 pass-by-rvalue-ref 函数相比,使用 pass-by-value 函数可能会引入额外的复制构造。

    查看https://stackoverflow.com/a/7587151/1190077对相关问题Do I need to overload methods accepting const lvalue reference for rvalue references explicitly?的回答。

    【讨论】:

      【解决方案3】:

      是的,第一个 (Vectype&amp;&amp; vec) 不会接受 const 对象或简单的左值。

      如果你想像你一样将对象保存在里面,最好在界面中复制(或移动,如果你传递一个右值)然后移动,就像你在第二个示例中所做的那样。

      【讨论】:

        猜你喜欢
        • 2016-10-22
        • 2012-01-16
        • 2012-10-14
        • 1970-01-01
        • 2020-01-03
        • 2013-08-20
        • 2013-08-01
        • 2010-12-17
        相关资源
        最近更新 更多