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