0

I use a std::unique_ptr with a custom deleter as a value of a std::map as follows:

#include <iostream>
#include <memory>
#include <map>

void deleter(int* p){
    std::cout<<"Deleting..."<<std::endl;
    delete p;
}

int main()
{   
    std::map<char, std::unique_ptr<int, void(*)(int*)>> a;
    std::unique_ptr<int, void(*)(int*)> p{new int{3}, deleter}; 
    a['k'] = std::move(p);
}

When inserting a value, I use std::move, but it will not compile.

What am I doing wrong?

You see the errors following link.

https://wandbox.org/permlink/fKL4QDkUTDsj4gDc

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
yawara
  • 11
  • 2

2 Answers2

5

a['k'] will default construct the value type of the map if the key does not exist. Since your unique_ptr uses a custom deleter, it is not default constructable. You will have to use either map::emplace() or map::insert() to add the unique_ptr to the map. If you want to know if the element exists or not before you do so, you can use either map::count() or map::find().

If you can use C++17, you can use map::try_emplace() instead, which will only add the object if the key does not exist, saving you a lookup.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • If you read the compiler's error messages more carefully, the default constructor issue is actually pointed out to you: "*required from `...::operator[](...)` ... error: no matching function for call to **`std::unique_ptr::unique_ptr()`***" – Remy Lebeau Jun 28 '18 at 20:48
0

The bug is in the default construction of the map entry before the assignment!

Sorry no time to work up the answer, but generally I would use insert instead?

Gem Taylor
  • 5,381
  • 1
  • 9
  • 27