将对象插入不允许复制构造函数的 std::deque

Posted

技术标签:

【中文标题】将对象插入不允许复制构造函数的 std::deque【英文标题】:Insert object into std::deque that does not allow copy constructor 【发布时间】:2021-11-27 15:38:34 【问题描述】:

我使用std::deque 来保存一些对象,只要我可以使用deque.emplace_front 添加新元素,它就可以很好地工作。但是,现在我想用已经存在的对象替换双端队列的元素。当我尝试执行以下操作时

auto it = mydeque.begin();
++it;
mydeque.insert(it, object);
mydeque.erase(it);

我收到一个错误,因为我的对象不允许复制。我该如何解决这个问题?

编辑:

我的对象是 hp::DoFHandler<dim> 类型,记录在这里:https://www.dealii.org/current/doxygen/deal.II/classhp_1_1DoFHandler.html。 我不能使用emplace的原因是因为这个方法构造了一个新对象,而我想插入我现有的对象。 我可以创建一个最小的工作示例,但由于我使用 FEM 框架https://www.dealii.org/,因此需要安装它或下载 Docker 映像。

【问题讨论】:

为了完整起见,您应该显示minimal reproducible example 对象是否支持复制分配? 如果您成功使用emplace_front 进行正面插入,为什么不使用emplace 进行中间插入? std::deque 有一个 emplace 函数,其工作方式与 insert 一样,但允许您使用 emplace 机制。另外,为什么不直接重新分配对象,即*it = std::move(object) emplace 方法创建一个新对象,而我想插入一个现有对象。重新分配对象可能会起作用,我不知道这种可能性。 【参考方案1】:

我不能使用 emplace 的原因是因为这个方法构造了一个新对象,而我想插入我现有的。

容器的元素始终是一个不同的对象。如果插入现有对象,则必须复制或移动该对象。

我收到一个错误,因为我的对象不允许复制。我该如何解决这个问题?

如果类型允许移动,则可以使用std::move。否则,您无法将预先存在的对象插入到容器中。


一些不可移动类型的 XY 解决方案:

最初使用emplace在容器中创建对象来避免此问题。 使用间接。与其将hp::DoFHandler<dim> 对象存储在容器中,不如存储一些引用此类对象的东西,例如指针。这种方法的缺点是必须确保指针的生命周期不超过指向对象的生命周期。使用共享所有权 (std::shared_ptr) 是确保这一点的一种简单方法,但它还有其他潜在的缺点。

【讨论】:

以上是关于将对象插入不允许复制构造函数的 std::deque的主要内容,如果未能解决你的问题,请参考以下文章

显式复制构造函数和统一初始化

如果对象没有默认构造函数并且我不允许在其类定义中创建一个对象,如何将对象放入节点中?

在非构造的“对象”上调用非虚拟成员函数是不是定义明确? [复制]

复制构造函数的运用

Java拷贝构造函数初尝试

Postgres 创建触发器函数以在允许插入之前将值从一列复制到另一列