Reputation: 3267
in a class with the following member and method:
std::unordered_map<std::string, std::unique_ptr<test::Test>> m_Tests;
void test::TestMenu::addTest(const std::string &testName, std::unique_ptr<test::Test> test) {
m_Tests.emplace(testName, test);
}
called like this:
testMenu.addTest("Test Clear Color", std::make_unique<test::TestClearColor>());
The compiler delivers the error:
error: no matching function for call to 'construct_at'
std::construct_at(__p, std::forward<_Args>(__args)...);
My question is why is C++ giving me this error?
Upvotes: 1
Views: 1793
Reputation: 17464
This:
m_Tests.emplace(testName, test);
will try to copy test
, because (a) it is an lvalue expression, (b) expressions never have reference type, and (c) emplace
does not take an lvalue reference.
unique_ptr
s cannot be copied.
This is what std::move
is for!
m_Tests.emplace(testName, std::move(test));
Now you have an rvalue expression, which is perfectly suited to bind to the rvalue reference that emplace
does take.
I'm actually slightly slightly lying here, and things are a bit more complicated since emplace
is variadic. But whatever. The important thing is that you're creating another link in the chain of ownership for this unique_ptr
, ultimately passing ownership on to the map, and std::move
is the way to do that.
Upvotes: 4