I'm getting this weird error when inserting an element into std::unordered_map using emplace function but not if I use operator[] function overload. This is my code:
#include <iostream>
#include <unordered_map>
#include <memory>
class B {
public:
    B() = default;
    ~B() = default; 
};
class A {
public:
    A() = default;
    ~A() = default;
    
    std::unique_ptr<B> b_ptr;
};
int main() {
    std::unordered_map<std::string, A> mp;
    // mp.emplace("abc", A()); // gives compiler here
    auto& a = mp["def"];
}
I'm getting huge error print when compiled. This is a short note of error: template argument deduction/substitution failed
When you use emplace like mp.emplace("abc", A()); what you are doing is creating a temporary A, and that object is then copied/moved into the object that emplace is going to construct.  When you did ~A() = default; in the class, that gets rid of the compiler supplied default move constructor, and the copy constructor is implicitly deleted because std::unique_ptr can't be copied so the A() can't be moved or copied into the object emplace is going to create.
You can fix this by using the std::piecewise_construct taged version of emplace to forward the parts of the key value pair to emplace like
mp.emplace(std::piecewise_construct,    // call the piecewise_construct overload
          std::forward_as_tuple("abc"), // forwards "abc" to the key
          std::forward_as_tuple());     // forwards nothing to the value so it can be default constructed
          
or you could just add a move constructor to A using
A(A&&) = default;
so that emplace can move the A() you created in main into mp.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With