This snippet of code doesn't seem to work because the unique pointer gets stored into a pair object and then is attempted to be copied from it. Can this be avoided?
std::unordered_map<std::string,std::unique_ptr<int>> _map {
{"hello", std::make_unique<int>(7)}
};
A full code example and compilation error can be seen here http://cpp.sh/7uc3a
Yes, by not using list-initialization.
std::unordered_map<std::string,std::unique_ptr<int>> _map;
_map.insert({"hello", std::make_unique<int>(7)});
std::unordered_map
needs to call either the copy or move constructor in order to store any keys and values in its internal buffer. In the case of std::unique_ptr
, the copy constructor is deleted, since making a copy of a std::unique_ptr
would make it, well, not unique at all. That leaves only the move constructor.
The problem is with how you're initializing your map:
std::unordered_map<std::string,std::unique_ptr<int>> _map {
{"hello", std::make_unique<int>(7)}
};
You're initializing your map's values using a std::initializer_list
.
From cppreference:
An object of type std::initializer_list is a lightweight proxy object that provides access to an array of objects of type const T.
Effectively, all of the values in your initializer list are const. That means the move constructor on your std::unique_ptr
can't be called, since moving an object generally requires modifying the original instance. Since the std::unique_ptr
can't be moved, the compiler falls back on the copy constructor, which is why it ends up complaining that the copy constructor is deleted.
The snippet I posted works because insert
accepts a non-const std::pair
, which means that the std::unique_ptr
is non-const, and can have its move constructor called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With