std::list 模板在其实例类型中是否需要复制构造函数(或等价物)?

Does std::list template require a copy constructor (or equivalent) in its instance type?

我有一个 class,每一个实例都要被计算在内,创建和销毁都受到严格监管。不允许随机移动、复制、临时 - 一旦通过专用函数创建,实例只能通过引用和指针 "passed around"。

为此,我删除了这个 class' 复制构造函数和赋值运算符。

这些实例本应保存在 std::list 中,由 emplace_back() 创建,按需移除且从未打算移动。但是我收到有关已删除的复制构造函数的错误。

 In constructor 'std::_List_node<_Tp>::_List_node(_Args&& ...) 
 error: deleted function 'Reader::Reader(const Reader&) 
          stl_list.h:103: error: used here

有没有办法让它工作?我不需要手工雕刻的 std::list 替代品?

标题中问题的答案是“视情况而定”。

如果您的 class 确实有移动构造函数,您将能够使用移动构造函数。如果您的 class 没有移动构造函数,那么将使用复制构造函数。

列表中的 object 必须以某种方式构建。 emplace_back 使它尽可能高效,但它仍然需要构造一个 object。来自http://en.cppreference.com/w/cpp/container/list/emplace_back使用placement-new在容器提供的位置构造元素in-place。

emplace_back 的参数是另一个 object 时,放置 new 将最终调用复制构造函数或移动构造函数。

如果 emplace_back 的参数只是构造 object 所需的数据,那么您不需要复制构造函数或移动构造函数。


Is there a way to make this work?

如果您或您的团队关于复制构造函数和移动构造函数的政策未公开讨论,您将不得不使用变通方法。

解决方法 1:

存储指向列表中 object 的指针。这是最简单的解决方法,只要您可以确保 object 不会在列表背后被删除并让列表保留悬空指针。

解决方法 2:

存储列表中 object 的 non-pointer 句柄。这将需要您编写一些簿记代码。如果您可以添加以下功能:

  1. 给定一个指向 object 的指针,得到一个整数值。整数值可以用作 object.
  2. 的 non-pointer 句柄
  3. 根据先前返回的句柄获取指向 object 的指针。

您可以使用句柄列表轻松管理。

通过保留几张随 object 的构建和删除而更新的地图,可以轻松实现上述目标。每次创建 object 时,都会将条目添加到映射中。每次删除 object,都会从映射中删除条目。