对于启用移动的课程,这两者之间有区别吗?
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&&
不会绑定。除此之外,在rvalue情况下,Foo::bar(Vectype)
将使用移动构造函数构建向量,或者更好地将副本全部放在一起,看到vec是一个右值(是吗?)。那么有没有令人信服的理由不通过值声明而不是左值和右值超载?
(考虑到我需要在任何情况下将向量复制到成员变量。)
答案 0 :(得分:5)
pass-by-value版本允许lvalue参数并复制它。无法使用左值参数调用rvalue-reference版本。
当您根本不需要更改或复制参数时使用const Type&
,当您需要可修改的值但不关心如何获取它时使用pass-by-value,并使用{{当你想要根据上下文发生稍微不同的事情时,1}}和Type&
会重载。
答案 1 :(得分:3)
只要参数类型具有高效的移动构造函数,传递值函数就足够了(并且等效),在本例中对于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?。
答案 2 :(得分:2)
是的,第一个(Vectype&& vec)
不接受const对象或只是左值。
如果你想像你一样保存对象,最好在界面中复制(或移动,如果你传递右值)然后移动,就像你在第二个例子中那样。