[英]C++, take const lvalue and rvalue reference in a function
我有一些方法需要让他们能够通过const lvalue(将其复制到此处)和rvalue引用(用于速度)来获取变量
struct Object {
...
Object(Object&& o) { ... }
Object(const Object& o) { ... }
...
};
...
struct SomeClass {
...
Object arr[7];
void copy(int pos,const Object& o) { arr[pos] = o; }
void copy(int pos,Object&& o) { arr[pos] = o; }
...
};
因此,在SomeClass中,两种复制方法是完全相同的。 唯一的区别是,在一个对象中将以const形式进行传递,将被复制,而在另一个对象中则被传递以供快速复制使用以作为右值引用。
这两种方法的代码完全相同。
现在,在上面的示例中并没有那么悲惨,但是,我的方法稍大一些,大约9-15行。 显然,解决方法是像在此一样复制它们,但是感觉不对。
如何重用复制方法的代码?
首先,在两种情况下都要进行副本分配:
void copy(int pos,const Object& o) { arr[pos] = o; }
void copy(int pos,Object&& o) { arr[pos] = o; }
如果有名称,则为左值。 在第二个函数中, o
有一个名称,因此它是一个左值(尽管是右值引用)。 您想要arr[pos] = std::move(o);
。
避免必须写两次copy
的通常方法是按值取o
并从其移走:
void copy(int pos, Object o) { arr[pos] = std::move(o); }
如果传递一个左值,然后将其赋值到arr[pos]
,则o
将被复制构造。 如果传递一个右值,则将构造o
,然后将其进一步分配给数组。 因此,在右值情况下,您仍然避免复制,但在两种情况下都需要多花钱。 如果搬家很便宜,应该没有多少额外的开销。
但是,请注意,这不适用于不支持移动语义的旧式类型。 在这种情况下,此函数将复制您所传递的内容,然后从该副本进行复制分配,而使用引用的两个重载将仅复制一份。
通用引用和std::forward
允许您实现完美的转发。 这是修改后的copy
:
template <typename T>
void copy(int pos, T&& o) {arr[pos] = std::forward<T>(o);}
如果您担心从其他类型到Object
隐式转换,则还可以在copy
正文中添加static_assert
。 如果传递一个左值Object
进行copy
,则T
将被推导为Object&
。 std::forward<Object&>
返回引用。 因此,将选择副本分配过载。 如果传递一个r值Object
进行copy
,则T
将被推导为Object
。 std::forward<Object&>
返回Object&&
。 由于std::forward<Object>(o)
也是一个右值,因此将选择移动分配运算符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.