无法将具有unique_ptr的对象推回std :: vector

时间:2019-03-20 20:07:13

标签: c++ unique-ptr move-constructor

我正在尝试创建一个实体,该实体可以包含指向其父代的指针和指向其子代的矢量。

问题是当我尝试将emplace_back或push_back返回到子向量时,我得到

Error C2280 'Entity::Entity(const Entity &)': attempting to reference a deleted function

由于我在实体中有一个unique_ptr。

我认为添加一个移动构造函数可以解决此问题,但并不能解决问题。

我在下面提供了一个最小的可验证可运行示例。

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

struct Entity
{
   //////// data
   unique_ptr<Entity> mParent;
   std::vector<Entity> mChildren;

   //////// ctors
   // default
   Entity() = default;
   // move
   Entity(Entity && entity): mParent{std::move(entity.mParent)}{}

   //////// functions
   void add_child(Entity const && entity)
   {
       mChildren.emplace_back(entity); // COMMENT OUT THIS LINE FOR FUNCTIONAL CODE
       //Error  C2280 'Entity::Entity(const Entity &)': attempting to reference a deleted function in... include\xmemory0 881
   };
};

int main()
{
   Entity entity;
   entity.add_child(Entity());
   return 0;
}

1 个答案:

答案 0 :(得分:2)

丢弃const

void add_child(Entity && entity)

,并使用:

mChildren.push_back(std::move(entity));

应用了以上两项更改后,它便为我编译了。

说明:您想在void push_back( T&& value );中呼叫emplace_back(或类似地使用vector<T>),其中TEntity。另一个重载是void push_back( const T& value );,它不会编译,因为它的实现(方法主体)尝试调用T的副本构造函数,而Entity没有副本构造函数。实现void push_back( T&& value );调用T的move构造函数,而Entity具有move构造函数,因此可以编译。

要确保调用void push_back( T&& value );,您要将Entity&&传递给push_back。为此,您需要上面的两个更改。没有任何一个,entity无法转换为Entity&&

另请参阅https://en.cppreference.com/w/cpp/container/vector/push_back