10

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

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&&不会绑定。除此之外,在右值的情况下,Foo::bar(Vectype)将使用移动构造函数构造向量,或者更好地忽略副本,因为 vec 是一个右值(会吗?)。那么是否有令人信服的理由不喜欢通过值声明而不是左值和右值重载?(考虑在任何情况下我都需要将向量复制到成员变量。)

4

3 回答 3

6

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

当您根本不需要更改或复制参数时使用const Type&,当您想要一个可修改的值但不关心如何获取它时使用按值传递,当您希望发生稍微不同的事情时使用Type&和重载Type&&取决于上下文。

于 2013-06-27T13:10:10.703 回答
3

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

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

请参阅相关问题的答案https://stackoverflow.com/a/7587151/1190077我是否需要重载明确接受右值引用的 const 左值引用的方法?.

于 2014-04-09T20:49:45.120 回答
2

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

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

于 2013-06-27T13:07:59.480 回答