Да, не используя инициализацию списка.
std::unordered_map<std::string,std::unique_ptr<int>> _map;
_map.insert({"hello", std::make_unique<int>(7)});
std::unordered_map
необходимо вызвать конструктор копирования или перемещения для сохранения любых ключей и значений во внутреннем буфере.В случае std::unique_ptr
деструктор копирования удаляется, поскольку создание копии std::unique_ptr
сделает его, ну, не уникальным.Это оставляет только конструктор перемещения.Проблема в том, как вы инициализируете свою карту:
std::unordered_map<std::string,std::unique_ptr<int>> _map {
{"hello", std::make_unique<int>(7)}
};
Вы инициализируете значения своей карты, используя std::initializer_list
.
Из cppreference :
Объект типа std :: initializer_list - это легкий прокси-объект, который обеспечивает доступ к массиву объектов типа const T .
Эффективновсе значения в вашем списке инициализатора являются постоянными.Это означает, что конструктор перемещения на вашем std::unique_ptr
не может быть вызван, поскольку перемещение объекта обычно требует изменения исходного экземпляра.Так как std::unique_ptr
не может быть перемещен, компилятор возвращается к конструктору копирования, поэтому он жалуется, что конструктор копирования удален.
Фрагмент, который я разместил, работает, потому что insert
принимаетнеконстантный std::pair
, что означает, что std::unique_ptr
неконстантный, и его конструктор перемещения может называться.