[英]Passing rvalue reference to const lvalue reference paremeter
我试图理解C ++ 11 rvalue引用以及如何在我的代码中使用它们以获得最佳性能。
假设我们有一个A
类,它有一个指向大量动态分配数据的成员指针。
此外,一个方法foo(const A& a)
用A
类对象做某事。
我想,以防止拷贝构造A
从当一个对象被称为 A
被传递给函数foo
,因为在这种情况下,将执行底层堆数据的深层副本。
我测试了传递左值参考:
A a;
foo(a);
并传递右值引用:
foo(A());
在这两种情况下都没有调用复制构造函数。
这是预期的还是由于我的编译器(Apple LLVM 5.1)的一些优化? 这有什么说明吗?
这是预料之中的。 如果将参数传递给引用类型参数(无论是左值还是右值引用),则不会复制该对象。 这是整个参考点。
你所拥有的困惑很常见。 只有在按值传递对象时才会选择复制或移动构造函数。 例如:
void foo(A a);
将A
对象传递给此函数时,编译器将根据您传递的表达式是左值还是右值表达式来确定是使用复制还是移动构造函数。
另一方面,以下函数都不会尝试调用复制或移动构造函数,因为没有构造对象 :
void foo(A& a);
void foo(const A& a);
void foo(A&& a);
void foo(const A&& a);
重要的是要注意,你应该很少(如果有的话)有任何理由编写一个除了移动构造函数/赋值运算符之外的函数,它接受一个右值引用。 你应该在传递值和传递const
lvalue引用之间做出决定:
如果您无论如何都需要函数内部对象的副本(可能是因为您想要修改副本或将其传递给另一个函数),请按值( A
)进行。 这样,如果给你一个左值,它就必须被复制(你无法避免这种情况),但是如果给你一个右值,它将被最佳地移动到你的函数中。
如果您不需要该对象的副本,请使用const
左值引用( const A&
)。 这样,无论您是给出左值还是左值,都不会进行复制。 当您确实需要复制它时,不应该使用它,因为它会阻止您使用移动语义。
根据它的声音,你根本不会制作任何副本,因此const A&
参数可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.