C++ 列表模板在其实例类型中是否需要副本构造函数(或等效构造函数)?

C++ 列表模板在其实例类型中是否需要副本构造函数(或等效构造函数)?,c++,c++11,stdlist,deleted-functions,C++,C++11,Stdlist,Deleted Functions,我有一个类,每一个实例都要考虑,创造和破坏都要严格控制。不允许随机移动、复制和临时操作-一旦通过专用函数创建,实例只能通过引用和指针传递 为了实现这一点,我删除了这个类的复制构造函数和赋值操作符 这些实例应该保存在std::list中,由emplace_back创建,根据需要删除,并且永远不会移动。但是我得到了关于删除副本构造函数的错误 In constructor 'std::_List_node<_Tp>::_List_node(_Args&& ...) e

我有一个类,每一个实例都要考虑,创造和破坏都要严格控制。不允许随机移动、复制和临时操作-一旦通过专用函数创建,实例只能通过引用和指针传递

为了实现这一点,我删除了这个类的复制构造函数和赋值操作符

这些实例应该保存在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的替代品?

标题中问题的答案是这取决于具体情况

如果您的类确实有移动构造函数,则可以使用移动构造函数。如果您的类没有移动构造函数,则将使用复制构造函数

列表中的对象必须以某种方式构造。emplace_back使其尽可能高效,但它仍然需要构造一个对象。From:使用placement new在容器提供的位置在位构造图元

当emplace_back的参数是另一个对象时,placement new将最终调用复制构造函数或移动构造函数

 In constructor 'std::_List_node<_Tp>::_List_node(_Args&& ...) 
 error: deleted function 'Reader::Reader(const Reader&) 
          stl_list.h:103: error: used here
如果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
有没有办法让这一切顺利进行

如果您或您的团队关于复制构造函数和移动构造函数的策略未开放供讨论,则必须使用变通方法

围绕1: 存储指向列表中对象的指针。这是最简单的解决方法,只要您能够确保对象不会在列表背后被删除,并且列表保持悬空指针不变

围绕2: 存储指向列表中对象的非指针句柄。这将需要您的一些簿记代码。如果您可以将此功能添加到:

给定指向对象的指针,获取整数值。整数值可用作对象的非指针句柄。 获取指向给定先前返回句柄的对象的指针。 您可以使用句柄列表轻松地进行管理


通过保存两个地图(这些地图随着对象的构建和删除而更新),可以很容易地完成上述操作。每次创建对象时,都会向贴图添加条目。每次删除对象时,都会从映射中删除条目。

是否保留移动语义?标准的哪个版本?哪一行代码导致错误?添加移动构造函数?如何将对象添加到列表?@MooingDuck:list.emplace_backparams;我会说,我有点困惑,为什么std::list首先需要一个复制或移动的ctor——在没有任何复制或移动的情况下,技术上不能在最后一个位置创建新对象吗?这是标准中的疏忽还是std::list必须能够移动列表中存储的对象?@cdhowie,列表中的对象必须以某种方式构造。emplace_back使其尽可能高效,但它仍然需要构造一个对象。From:使用placement new在container.Right提供的位置在位构造元素。为什么需要复制或移动对象?除非OP试图将对象移动到列表中。也许OP的解决方案应该是首先在那里安置物体?我想这个问题对于如何构造这个对象有点不清楚。@ CDHOWIE,当将EffisteBead的参数作为另一个对象时,new new将最终调用复制构造函数或移动构造函数。@ R.SaHu是否考虑将该评论放置到新的调用复制/移动构造函数中?这是我需要完全理解你答案的缺失环节。