简体   繁体   English

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

[英]Can't push_back an object with a unique_ptr to a std::vector

I am trying to create an Entity which can hold a pointer to its parent and a vector to its children. 我正在尝试创建一个实体,该实体可以持有指向其父代的指针和指向其子代的向量。

The problem is when I try to emplace_back or push_back to the vector of children, I get 问题是当我尝试将emplace_back或push_back返回到子向量时,我得到

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

Due to the fact I have a unique_ptr in the Entity. 由于这个事实,我在实体中有一个unique_ptr。

I thought that adding a move-constructor would solve this problem but it has not. 我以为添加一个移动构造函数可以解决此问题,但事实并非如此。

I have included a minimal verifiable runnable example here below. 我在下面提供了一个最小的可验证可运行示例。

#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;
}

Drop the const : 删除const

void add_child(Entity && entity)

, and use: ,并使用:

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

Applying these 2 changes above made it compile for me. 应用上面的这2个更改使它可以为我编译。

Explanation: You want to call void push_back( T&& value ); 说明:您要调用void push_back( T&& value ); (or similarly with emplace_back ) in vector<T> , where T is Entity . (或与emplace_back相似)在vector<T> ,其中TEntity The other overload is void push_back( const T& value ); 另一个重载为void push_back( const T& value ); , which doesn't compile, because its implementation (method body) attempts to call the copy constructor of T , and Entity doesn't have a copy constructor. ,它不会编译,因为其实现(方法主体)尝试调用T的副本构造函数,而Entity没有副本构造函数。 The implementation void push_back( T&& value ); 实现void push_back( T&& value ); calls the move constructor of T , and Entity has a move constructor, so it compiles. 调用T的move构造函数,而Entity具有move构造函数,因此进行编译。

To make sure that void push_back( T&& value ); 确保void push_back( T&& value ); is called, you want to pass an Entity&& to push_back . 调用时,您要将Entity&&传递给push_back For that you need both changes above. 为此,您需要上面的两个更改。 Without either, entity can't be converted to Entity&& . 没有两者, entity就不能转换为Entity&&

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

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM