【问题标题】:Is using std::move to dump a member acceptable design?是否使用 std::move 转储成员可接受的设计?
【发布时间】:2017-03-07 03:09:12
【问题描述】:

假设我有一个类C,其唯一目的是填充一个属于C 成员的某种类型的容器con_m。所以C 拥有以特定方式填充con_m 的方法。在C 填满con 之后,我不再需要C,所以我想将con_n 转储到另一个变量中。但是C 实际上是一个函子,因为con_m 只能增量填充,因此不能是填充函数的本地对象。此外,该实现应该对用户隐藏,因此他不需要在返回 con_m 的函数上调用 std::move

template <class container_type> class C {

public:

  template <class T> void fill_some_more(const T &t) {
    // do stuff with t filling con_m by another increment
  }

  container_type dump_container() { return std::move(con_m); }

  container_type con_m;
};

int main() {
    C<std::vector<int>> c;
  while (some_condition) {
      c.fill_some_more(some_int);
  }
  auto con = c.dump_container();
}

std::move 的用法合适吗?

【问题讨论】:

  • 听起来C 的方法作为以容器为参数的独立函数可能会更好。如果容器一开始就不是成员,那么将容器从类中挖掘出来是不会有问题的。
  • 似乎取决于您的移动构造函数是否使源对象处于所需状态
  • 我会说不。一般来说,移动构造函数不需要将容器留空。
  • 不要因为目的不透明而认为这是一个好主意。其他人会看着它,扬起眉毛,要么弄清楚你在做什么,要么做出可怕的、导致崩溃的假设。

标签: c++ c++11 return factory move


【解决方案1】:

还应该对用户隐藏实现

移动对象的内容不是实现细节;这是该功能正在做的事情的一部分。通过移动对象的内容,您可以使对象丢失其内容,因此稍后调用的代码需要尊重这一事实。

C++ 标准委员会之所以让您必须大量使用std::move,是为了让阅读您的代码的人能够知道发生了什么。如果有人看到c.dump_container(),他们可能会认为倾销是通过副本发生的。如果他们看到std::move(c).dump_container(),并且如果他们看到他们不能在左值引用上调用它,那么参与其中的每个人都很清楚c 之后的状态。

运动应该是明确的。

当然,正如 Igor 在 cmets 中指出的那样,如果这些是作用于用户提供的容器的免费函数,而不是必须让容器成为某种类型的成员,这整个事情就可以避免。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2013-04-05
    相关资源
    最近更新 更多