I am missing something with std::make_shared
. Can't it resolve the type of a std::initializer_list
, or am I doing something else wrong?
#include <vector>
#include <memory>
class A {};
int main()
{
A a;
std::vector<A> veca{A(), A{}, a}; // this works ofc
std::vector<A> vecb({A(), A{}, a}); // this too
std::make_shared<std::vector<A>>(vecb); // and this, ofc
std::make_shared<std::vector<A>>({a}); // what's wrong here?
return 0;
}
Error:
main.cpp:21:41: error: too many arguments to function ‘std::shared_ptr<_Tp1> std::make_shared(_Args&& ...) [with _Tp = std::vector; _Args = {}]’
std::make_shared<std::vector<A>>({a});
^
In file included from /usr/include/c++/6/memory:82:0,
from main.cpp:10:
/usr/include/c++/6/bits/shared_ptr.h:632:5: note: declared here
make_shared(_Args&&... __args)
^~~~~~~~~~~
Live example: https://onlinegdb.com/r1DlHquDL
Consider the following minimal example of your problem:
template <typename... Ts>
void f(Ts&&...); // replacement for std::make_shared
int main()
{
f({1});
}
This case is described in the C++ Standard in [temp.deduct.call/1]:
Template argument deduction is done by comparing each function template parameter type (call it
P
) that contains template-parameters that participate in template argument deduction with the type of the corresponding argument of the call (call itA
) as described below. If removing references and cv-qualifiers fromP
givesstd::initializer_list<P′>
orP′[N]
for someP′
andN
and the argument is a non-empty initializer list ([dcl.init.list]), then deduction is performed instead for each element of the initializer list independently, takingP′
as separate function template parameter typesP′i
and thei
th initializer element as the corresponding argument. In theP′[N]
case, ifN
is a non-type template parameter,N
is deduced from the length of the initializer list. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context ([temp.deduct.type]).
In your case, the last sentence applies. Interestingly, the error message says something else with GCC, which is weird. With Clang, the error message is clear:
error: no matching function for call to 'f'
note: candidate template ignored: substitution failure: deduced incomplete pack <(no value)> for template parameter 'Ts'