简体   繁体   English

std :: list模板的实例类型是否需要副本构造函数(或等效副本)吗?

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

I have a class, for which every instance is to be accounted for, creation and destruction regulated tightly. 我有一堂课,每个实例都要负责,创建和销毁都受到严格的管理。 No random moves, copies, temporaries allowed - once created through a dedicated function, the instance can be "passed around" only through references and pointers. 不允许随意移动,复制和临时使用-一旦通过专用功能创建了实例,则只能通过引用和指针来“传递”实例。

To achieve that, I've deleted this class' copy constructor and assignment operator. 为此,我删除了此类的复制构造函数和赋值运算符。

The instances were meant to be kept in std::list, created by emplace_back(), removed on demand and never intended to move. 这些实例应保留在由emplace_back()创建的std :: list中,可按需删除并且从不打算移动。 But I'm getting errors about the deleted copy constructor. 但是我收到有关已删除的副本构造函数的错误。

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

Is there a way to make this work? 有没有办法使这项工作? Some alternative to std::list that I won't need to carve by hand? 我不需要手工雕刻的std :: list替代品吗?

The answer to the question in the title is "It depends". 标题中问题的答案是“取决于”。

If your class does have a move constructor, you will be able to use the move constructor. 如果您的类确实具有move构造函数,则可以使用move构造函数。 If your class does not have a move constructor, then the copy constructor will be used. 如果您的类没有move构造函数,则将使用copy构造函数。

The object in the list has to be constructed somehow. 列表中的对象必须以某种方式构造。 emplace_back makes it as efficient as possible but it still needs to construct an object. emplace_back使它尽可能高效,但是仍然需要构造一个对象。 From http://en.cppreference.com/w/cpp/container/list/emplace_back : uses placement-new to construct the element in-place at the location provided by the container. 来自http://en.cppreference.com/w/cpp/container/list/emplace_back使用placement-new在容器提供的位置就地构造元素。

When the argument to emplace_back is another object, the placement new will end up calling either the copy constructor or the move constructor. emplace_back的参数是另一个对象时,new放置将最终调用复制构造函数或move构造函数。

If the argument(s) to emplace_back is just the data needed to construct an object, then you don't need a copy constructor or a move constructor. 如果emplace_back的参数只是构造对象所需的数据,则您不需要复制构造函数或move构造函数。


Is there a way to make this work? 有没有办法使这项工作?

If your, or your team's, policy regarding copy constructor and move constructor is not open for discussion, you will have to use a work around. 如果您或您团队的有关复制构造函数和move构造函数的政策尚未公开讨论,则您将不得不使用变通方法。

Work around 1: 解决方法1:

Store pointers to the objects in the list. 将指针存储到列表中的对象。 This is the simplest work around as long as you can ensure that objects are not deleted behind the list's back and leave the list holding on to dangling pointers. 这是最简单的解决方法,只要您可以确保不删除对象,就可以将对象保留在列表的后面,并使列表保持悬空的指针。

Work around 2: 解决方法2:

Store a non-pointer handle to the objects in the list. 将非指针句柄存储到列表中的对象。 This will require some book keeping code on your part. 这将需要您自己执行一些簿记代码。 If you can add the ability to: 如果可以添加以下功能:

  1. Get an integral value given a pointer to an object. 给定指向对象的指针,获取整数值。 The integral value can be used as the non-pointer handle to the object. 整数值可用作对象的非指针句柄。
  2. Get a pointer to the object given the previously returned handle. 给定先前返回的句柄的对象的指针。

you can easily manage by using a list of handles. 您可以使用句柄列表轻松进行管理。

The above can be easily accomplished by keeping couple of maps that are updated with construction and deletion of objects. 通过保留几个通过构造和删除对象进行更新的地图,可以轻松实现上述目标。 Every time you create an object, you add entries to the maps. 每次创建对象时,都将条目添加到地图中。 Every time you delete an object, you remove entries from the maps. 每次删除对象时,都会从地图中删除条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std :: function的copy-constructor是否要求模板类型的参数类型为完整类型? - Does std::function's copy-constructor require the template type's argument types to be complete types? 为什么 std::array 需要大小作为模板参数而不是构造函数参数? - Why does std::array require the size as a template parameter and not as a constructor parameter? 为什么std :: enable_if需要第二个模板类型? - Why does std::enable_if require the second template type? 为什么 std::vector 构造函数通过复制接受初始化列表? - Why does the std::vector constructor accept initializer list by copy? std :: initializer_list是否具有复制构造函数,是否曾经使用过? - Does std::initializer_list have a copy constructor and is it ever used? 为什么`std :: pair <int, movable> `需要一个[删除]`const&`复制构造函数? - Why does `std::pair<int, movable>` require a [deleted] `const&` copy constructor? 为什么std :: random_device将其复制构造函数定义为已删除? - Why does std::random_device define its copy constructor as deleted? 使 std::function 需要复制构造函数的基本原理 - Rationale behind making std::function require copy constructor std::vector 是否有引用的复制构造函数? - Does std::vector have a copy constructor for references? 为什么std :: thread在其构造函数中等待? - Why does std::thread wait in its constructor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM