Невозможно вернуть объект с уникальным_треком в std :: vector - PullRequest
1 голос
/ 20 марта 2019

Я пытаюсь создать сущность, которая может содержать указатель на своего родителя и вектор на своих потомков.

Проблема в том, что когда я пытаюсь emplace_back или push_back для вектора детей, я получаю

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

Из-за того, что в Entity у меня есть 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 Ответ

2 голосов
/ 20 марта 2019

Отбросьте const:

void add_child(Entity && entity)

и используйте:

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

Применение этих двух изменений привело к его компиляции для меня.

Объяснение:Вы хотите позвонить void push_back( T&& value ); (или аналогично emplace_back) в vector<T>, где T равно Entity.Другая перегрузка - void push_back( const T& value );, которая не компилируется, потому что ее реализация (тело метода) пытается вызвать конструктор копирования T, а Entity не имеет конструктора копирования.Реализация void push_back( T&& value ); вызывает конструктор перемещения T, а Entity имеет конструктор перемещения, поэтому он компилируется.

Чтобы убедиться, что вызывается void push_back( T&& value );, необходимо передать Entity&& до push_back.Для этого вам нужно оба изменения выше.Без них entity не может быть преобразовано в Entity&&.

См. Также https://en.cppreference.com/w/cpp/container/vector/push_back.

...