I have a class that contains a unique_ptr. I want to place instances of this class inside a container (specifically std::map). This works using std::move
and .emplace
however, I would like to perform all this initialization within the container's initializer list. Is this possible?
I suspect Foo
gets initialized in the initializer list then copied which is causing the problem. I've tried added a std::move
in the initializer list but that hasn't solved the problem.
class Foo
{
public:
std::unique_ptr<std::string> my_str_ptrs;
}
Compilation Fails "attempting to access a deleted function". This is an example of what I want to do
std::map<std::string, Foo> my_map{
{"a", Foo{}}
};
Compilation Succeeds
std::map<std::string, Foo> my_map;
my_map.emplace("a", Foo{});
CodePudding user response:
It's fault of std::initializer_list
, if you look at it's begin/end member functions, they return const T*
, which means it will force std::map
to try use the copy constructor of your Foo
, which is deleted
as std::unique_ptr
can not be copied.
This issue is not unique to std::map
, any container which allows you to initialize it with std::initializer_list
will really copy the arguments from an initializer list.
The C standard requires that during such initialization there's a temporary const T[N]
array, which the std::initializer_list
points to, const
disables moves from it.