Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to uniform initialize map of unique_ptr?

I have this code to initialize map from into to unique_ptr.

auto a = unique_ptr<A>(new A());
map<int, unique_ptr<A>> m;
m[1] = move(a);

Can I use uniform initialize this? I tried

map<int, unique_ptr<A>> m {{1, unique_ptr<A>(new A())}};    

But I got an error.

Some part of error message is

In instantiation of 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, std::unique_ptr<A, std::default_delete<A> > >&}; _Val = std::pair<const int, std::unique_ptr<A> >]': ... In file included from /opt/local/include/gcc48/c++/memory:81:0,
                 from smart_pointer_map.cpp:3: /opt/local/include/gcc48/c++/bits/unique_ptr.h:273:7: error: declared here
       unique_ptr(const unique_ptr&) = delete;

   ^
like image 355
prosseek Avatar asked Jun 18 '13 23:06

prosseek


2 Answers

unique_ptr is movable, but not copyable. initializer_list requires copyable types; you can't move something out of an initializer_list. Unfortunately, I believe what you want to do isn't possible.

Incidentally, it would be more helpful to know which specific error you got. Otherwise, we have to guess whether you did something wrong and what, or whether what you want to do isn't implemented in your compiler, or is simply not supported in the language. (This is most helpful along with minimal reproduction code.)

like image 151
Adam H. Peterson Avatar answered Sep 29 '22 18:09

Adam H. Peterson


As a workaround and especially when you want to have a const map containing unique_ptr, you can use a lambda executed in place. It is not an initializer list, but the result is similar:

typedef std::map<uint32_t, std::unique_ptr<int>> MapType;
auto const mapInstance([]()
{
   MapType m;
   m.insert(MapType::value_type(0x0023, std::make_unique<int>(23)));
   return m;
}());

or even simpler without typedef using make_pair:

auto const mapInstance([]()
{
   std::map<uint32_t, std::unique_ptr<int>> m;
   m.insert(std::make_pair(0x0023, std::make_unique<int>(23)));
   return m;
}());
like image 38
JackMartinKurt Avatar answered Sep 29 '22 18:09

JackMartinKurt