jeudi 3 août 2017

Proper usage of unique_ptr: emplace compiles while insert produces compiler errors (Map of lists )

Context:

I'm trying to learn smart pointers and I came across a case I don't understand.

I'm creating an unordered_map of unique_ptr<list<int>>. Declared as following:

unique_ptr<unordered_map<uint32_t, unique_ptr<list<uint32_t>>>> mymap;

The map and its contents are private data of a class and I want them to be destroyed when the class is destroyed. Therefore I use a unique_ptr for the map and for each list.

Problem:

When I call emplace, like so:

mymap->emplace(index, make_unique<list<uint32_t>>());

My program compiles just fine. It also works when I call insert creating pair explicitly:

mymap->insert(std::make_pair(index, std::make_unique<std::list<uint32_t>>()));

However, the following line:

mymap->insert({index, make_unique<std::list<uint32_t>>()});

produces the following errors (GCC in Linux Ubuntu)):

/usr/include/c++/5/ext/new_allocator.h:120:4: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const unsigned int; _T2 = std::unique_ptr >]’ { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

From the this answer I learned that the difference between the two methods is that insert copies or moves a key-value pair into the container, while emplace builds it in place. So perhaps the problem is that I'm not properly using the unique_ptr?

Question: Why the first two calls succeed while the third fails?

Aucun commentaire:

Enregistrer un commentaire