Putting an std::unique_ptr
inside an std::tuple
works without any issues, but when the tuple
contains another tuple
together with a unique_ptr
as elements, then the compiler throws an error.
Example:
std::tuple<int, std::unique_ptr<Entity>> tupleA {1, std::move(new Entity)};
//this line throws an error!
std::tuple<std::tuple<int, int>, std::unique_ptr<Entity>> tupleB {{1, 1}, std::move(new Entity)};
error: no matching constructor for initialization of ´std::tuple<std::tuple<int, int>,std::unique_ptr<Entity>>´
note: candidate constructor template not viable: cannot convert initializer list argument to ´std::allocator_arg_t´
What exactly is the Problem here?
TL;DR
Change your code so it reads
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
Details
Your compiler tells you what is wrong. It says (MSVC in this case)
error C2440: 'initializing': cannot convert from 'initializer list' to 'std::tuplestd::tuple<int,int,std::unique_ptr<Derived,std::default_delete>>'
So instead of using the initializer list go like this
std::tuple<std::tuple<int, int>, std::unique_ptr<Derived>> tupleB{std::make_tuple(1,1), std::move(new Derived)};
The issue is the following:
When a container is initialized with values within braces, like { 1, 1}, this is deduced to type std::initializer_lists<const char *>
. In turn the compiler looks for a container constructor which takes an initializer list as a parameter.