Пример живого кода Я пытаюсь сохранить в векторе вариант указателей на шаблонные версии базового класса. Указатели boost :: variant содержатся в структуре. Он отлично работает, если ...

0
tomocafe 24 Окт 2020 в 00:26

2 ответа

Лучший ответ

Две вещи:

Во-первых, вы должны переместить g в конструктор Category, поскольку вариант не подлежит копированию, если какой-либо из его членов не подлежит копированию.

Во-вторых, хотя каждое преобразование в цепочке AgeGetter* в Getter<int>* в std::unique_ptr<Getter<int>> в Category является неявным, C ++ выполняет только ограниченное количество неявных преобразований. В общем, эта цепочка слишком длинная, и вы можете исправить ее, например, используя emplace_back(std::make_unique<G>()) вместо emplace_back(new G()).

Кроме того, это безопаснее, поскольку если emplace_back выбрасывает (что может), new G() не будет удален и, следовательно, утечка. Но деструктор unique_ptr, возвращенный std::make_unique<G>(), будет вызываться, если emplace_back выбрасывает, и, следовательно, утечки не будет. Вы всегда должны стараться избегать сырых new в своем коде.

2
n314159 23 Окт 2020 в 23:10

Проблема в том, что как только вы используете unique_ptr, struct Category становится недоступным для копирования. Он по-прежнему подвижен, поэтому вы можете изменить его конструктор на:

Category(GetterVariant g) :
      getter(std::move(g))
    {}
0
Eugene 23 Окт 2020 в 23:03