Создайте unordered_map со значением value_type для unique_ptr - PullRequest
4 голосов
/ 24 сентября 2019

Этот фрагмент кода, похоже, не работает, поскольку уникальный указатель сохраняется в парном объекте, а затем пытается скопировать его.Можно ли этого избежать?

std::unordered_map<std::string,std::unique_ptr<int>> _map {
    {"hello", std::make_unique<int>(7)}
};

Полный пример кода и ошибка компиляции можно увидеть здесь http://cpp.sh/7uc3a

1 Ответ

5 голосов
/ 24 сентября 2019

Да, не используя инициализацию списка.

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 неконстантный, и его конструктор перемещения может называться.

...