Эмплейс обратно проваливается на месте строительства

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

// Defined utilities:
ModuleClusterPlot(Type typeArg, const int& layer, const int& module, const int& ladder, const int& startEventArg, const int& endEventArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;

Вызвать конструктор через emplace back не удалось, потому что он пытается вызвать конструктор перемещения (почему?):

moduleClusterPlots.emplace_back(t_type, t_layer, t_module, t_ladder, i, i);

Что я здесь не так делаю? я использую gcc 7.1.0 Жека std=c++14 флаг.

Минимальный пример:

#include <vector>

class ModuleClusterPlot
{
public:
enum Type
{
foo = 0,
bar
};

ModuleClusterPlot(Type typeArg);
~ModuleClusterPlot();
// Invalid utilities
ModuleClusterPlot(ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot(ModuleClusterPlot&& t_other) = delete;
ModuleClusterPlot& operator=(const ModuleClusterPlot& t_other) = delete;
ModuleClusterPlot& operator=(ModuleClusterPlot&& t_other) = delete;

};

int main()
{
std::vector<ModuleClusterPlot> collection;
collection.emplace_back(ModuleClusterPlot::foo);
}

Как я могу предотвратить вызов конструктора перемещения здесь?

-3

Решение

std::vector<T>::emplace_back Требуется конструктор перемещения или копирования. Причина в том, что может потребоваться перераспределение памяти и перемещение / копирование существующих объектов в новый буфер.

Даже если вы вызываете его только для пустого вектора, который фактически не должен перемещать существующие объекты, помните, что та же функция emplace_back может использоваться на пустых и непустых векторах. Функция не может знать, что она используется только из пустого состояния, поэтому, когда создается экземпляр функции-члена, код для работы с непустым вектором также должен быть действительным.

1

Другие решения

Вы нарушаете ограничения emaplce_back, Если мы посмотрим на таблицу 101 из [sequence.reqmts], то получим

требует: T должен быть EmplaceConstructible в X из аргументов. Для вектора T также должен быть MoveInsertable в X.

акцент мой

Так как ваш класс не является перемещаемым, он не будет работать с emplace_back,

Причина этого заключается в том, что size() становится больше, чем capacity() затем вектор должен выделить новое хранилище и переместить элементы в это новое хранилище. Если он не может этого сделать, то вектор не может функционировать как задумано.

0

По вопросам рекламы [email protected]