0

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?

El Marce
  • 3,144
  • 1
  • 26
  • 40
  • That's because in the third call you need to be able to construct a `std::unique_ptr` by copy but you are not allowed by design. In any case using an `unique_ptr>` is useless for what you show us of your problem, a simple `unordered_map>` would work in the same way. Actually even a `unordered_multimap` would suffice. – Jack Aug 03 '17 at 20:52
  • Thanks! I did not know about `unordered_multimap` I'll look into it. – El Marce Aug 03 '17 at 20:55

0 Answers0