c – 通过value或rvalue引用接受move-only参数

这个帖子 Pass by value vs pass by rvalue reference的接受答案说:

For move-only types (as std::unique_ptr),pass-by-value seems to be the norm…

我有点怀疑.假设有一些不可复制的类型,Foo,也不便宜;和一些类型的酒吧,有一个成员Foo.

class Foo {
public:
    Foo(const Foo&) = delete;
    Foo(Foo&&) { /* quite some work */ }
    ...
};

class Bar {
public:
    Bar(Foo f) : f_(std::move(f)) {}    // (1)
    Bar(Foo&& f) : f_(std::move(f)) {}  // (2)
    // Assuming only one of (1) and (2) exists at a time

private:
    Foo f_;
};

然后为以下代码

Foo f;
...
Bar bar(std::move(f));

构造函数(1)引发了2个移动结构,而构造函数(2)只引起了1.我还记得在Scott Meyers的有效现代C中阅读这个,但不记得哪个项目立即.

所以我的问题是,对于只移动类型(或者更一般来说,当我们想要转移参数的所有权时),我们不应该更喜欢通过rvalue引用以获得更好的性能

更新:我知道传递值构造函数/赋值运算符(有时称为统一转换器/赋值运算符)可以帮助消除重复的代码.我应该说我对(1)性能很重要的情况更感兴趣,(2)类型是不可复制的,因此没有接受const lvalue引用参数的重复ctors /赋值操作符.

更新2:所以我找到了Scott Meyers关于具体问题的博客http://scottmeyers.blogspot.com/2014/07/should-move-only-types-ever-be-passed.html.这个博客讨论了他在有效现代C的第41项中提倡的原因:

Consider pass by value only for copyable parameters…that are cheap to move…[and] always copied.

在该项目中有关于通过值与rvalue引用的广泛讨论,这里太多了.关键是,两种方式都有自己的优点和缺点,但是为了转移一个移动对象的所有权,通过rvalue引用似乎更可取.

解决方法

在这种情况下,我们可以吃蛋糕,吃饭.仅为Foo类型引用启用的模板构造函数使我们完美转发加上构造函数的单个实现:
#include <iostream>
#include <utility>

class Foo {
public:
    Foo() {}
    Foo(const Foo&) = delete;
    Foo(Foo&&) { /* quite some work */ }
};

class Bar {
public:
  template<class T,std::enable_if_t<std::is_same<std::decay_t<T>,Foo>::value>* = nullptr>
    Bar(T&& f) : f_(std::forward<T>(f)) {}  // (2)
    // Assuming only one of (1) and (2) exists at a time

private:
    Foo f_;
};

int main()
{
  Foo f;
  Bar bar(std::move(f));

  // this won't compile
//  Foo f2;
//  Bar bar2(f2);

}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...