Reputation: 487
For some reason, when trying to construct an unordered map (specifically by a pair), the map tried to copy the unique_ptr in the pair instead of move it. What am I doing wrong?
Here is an example (updated):
#include <unordered_map>
#include <memory>
class pointed
{
bool x;
int y;
public:
float key;
pointed( float key, bool x, int y ): x(x), y(y)
{ }
};
class test
{
std::unordered_map< float, std::unique_ptr< pointed > > my_map;
public:
template< typename... pointed_construction_t >
test( pointed_construction_t &&... pointed_parameter_pack ):
my_map
{
std::move
(
std::make_pair
(
pointed_parameter_pack.key,
std::move
(
std::make_unique< pointed >
(
std::forward< pointed_construction_t >
(
pointed_parameter_pack
)
)
)
)
)...
}
{ }
};
int main( )
{
float key = 2.f, key2 = 4.f;
bool x = true, x2 = false;
int y = 0, y2 = -1;
test t( pointed( key, x, y ), pointed( key2, x2, y2 ), pointed( 6.f, false, 500 ) );
}
error: use of deleted function
note: declared here
406 | unique_ptr(const unique_ptr&) = delete;
Upvotes: 0
Views: 294
Reputation: 96845
Using my_map{...}
is list-initialization and the compiler finds the std::initializer_list
constructor of std::unordered_map
. This constructs an initializer list which holds an array of const
elements. So your elements can't be moved from the list to the map.
You'll have to go inside the constructor and emplace the elements of the pair:
test(int key, pointed_construction_t&&... pointed_parameter_pack) {
map.emplace(key,
std::make_unique<pointed>(std::forward<pointed_construction_t>(
pointed_parameter_pack)...));
}
With your new update I am able to understand what you want. Use a fold expression so that emplace
is called for every pointed
argument.
(map.emplace(key,
std::make_unique<pointed>(
std::forward<pointed_construction_t>(pointed_parameter_pack))),
...);
Upvotes: 1