Reputation: 11
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
Error C2280 'Entity::Entity(const Entity &)': attempting to reference a deleted function
Due to the fact I have a unique_ptr in the Entity.
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;
}
Upvotes: 1
Views: 817
Reputation: 87311
Drop the const
:
void add_child(Entity && entity)
, and use:
mChildren.push_back(std::move(entity));
Applying these 2 changes above made it compile for me.
Explanation: You want to call void push_back( T&& value );
(or similarly with emplace_back
) in vector<T>
, where T
is Entity
. The other overload is 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. The implementation void push_back( T&& value );
calls the move constructor of T
, and Entity
has a move constructor, so it compiles.
To make sure that void push_back( T&& value );
is called, you want to pass an Entity&&
to push_back
. For that you need both changes above. Without either, entity
can't be converted to Entity&&
.
See also https://en.cppreference.com/w/cpp/container/vector/push_back.
Upvotes: 2