传递值或重新赋值

Pass by value or rvalue-ref

本文关键字:赋值 新赋值      更新时间:2023-10-16

对于支持移动的类,这两者之间有区别吗?

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

传递值版本允许使用左值参数并复制它。右值引用版本不能用左值参数调用。

当您根本不需要更改或复制参数时,请使用const Type&;当您想要一个可修改的值但不在乎如何获得它时,可使用pass-by-value;当您希望根据上下文发生一些稍微不同的事情时,可以使用Type&Type&&重载。

只要参数类型有一个有效的移动构造函数,传递值函数就足够了(也是等价的),在这种情况下,std::vector也是如此。

否则,与使用按右值传递ref函数相比,使用按值传递函数可能会引入额外的复制构造。

看看答案https://stackoverflow.com/a/7587151/1190077对于相关的问题,我是否需要为右值引用显式重载接受常量左值引用的方法。

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

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