传递值或重新赋值
Pass by value or rvalue-ref
对于支持移动的类,这两者之间有区别吗?
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)
不会接受常量对象或简单的左值。
如果你想像你那样把对象保存在里面,最好在接口中复制(或者如果你传递了一个右值就移动),然后移动,就像你在第二个例子中所做的那样。
相关文章:
- 变量在使用赋值语句赋值后恢复为以前的值
- 如何在 c++ 中正确声明/赋值变量的值
- 复制构造函数和赋值运算符的值类实现
- 为什么我的类工作正常,即使在返回垃圾值作为赋值运算符和空复制构造函数的返回之后
- 奇怪的 G++ 错误,带有关于左值和赋值的简单代码
- 用于捕获未赋值的 r 值的编译器选项
- 为可变结构赋值,该值必须易于复制
- 如何修复数组赋值从 ascii 值到 int
- 我想预先递增变量的赋值(预递增值大于 1)?
- 使用带有下标运算符的赋值运算符将值分配给 std::map
- 为什么 Visual C++ 编译器允许临时赋值到左值引用
- 需要左值作为赋值错误的左操作数通过 if 语句
- 左值和右值赋值错误
- 了解工厂方法和静态变量赋值的返回值优化 (Visual Studio)
- 运算符重载所需的左值作为赋值的左操作数
- 将真值赋给浮点值
- 指针向量,其元素用new初始化:赋给新值时会发生什么
- 增强标记器重新赋值
- c++函数返回右值,但可以为其赋一个新值
- 为什么可以给引用赋一个新值,以及如何使引用引用其他东西