c++ - Why is template parameter pack used in a function argument type as its template argument list not able to be explicit specified -
i have following piece of code:
template <typename, typename> struct aaa{}; template<typename ...args> void f(aaa<args...> *) {} int main() { f<int, int>(nullptr); }
this code results in compile error. when compiling using g++ -std=c++1z
error shows follows:
prog.cc: in function 'int main()': prog.cc:8:24: error: no matching function call 'f<int, int>(std::nullptr_t)' f<int, int>(nullptr); ^ prog.cc:5:6: note: candidate: template<class ... args> void f(aaa<args ...>*) void f(aaa<args...> *) {} ^ prog.cc:5:6: note: template argument deduction/substitution failed: prog.cc:8:24: note: mismatched types 'aaa<args ...>*' , 'std::nullptr_t' f<int, int>(nullptr);
using clang++ -std=c++1z
error is:
prog.cc:8:5: error: no matching function call 'f' f<int, int>(nullptr); ^~~~~~~~~~~ prog.cc:5:6: note: candidate template ignored: not match 'aaa<int, int, args...> *' against 'nullptr_t' void f(aaa<args...> *) {} ^ 1 error generated.
i running above in msys2 mingw-w64 environment. gcc version gcc 7.1.0 , clang version 4.0.0; standard library use both in gcc , in clang libstdc++ bundled gcc compiler.
in opinion, call function template foo
has template parameter explicitly specified template parameter pack , function argument type should specified. however, error diagnostics shown above seem suggest exact type of function parameter , nullptr
argument not match, seems issue possible when function argument deduction occurs. question is, why such error occur? compiler bug, or c++ standard have rules indicate original code ill-formed?
you may think compiler should deduce pack int ,int
, c++ standard explicitly requires behavior observed.
template argument deduction can extend sequence of template arguments corresponding template parameter pack, when sequence contains explicitly specified template arguments. [ example:
template<class ... types> void f(types ... values); void g() { f<int*, float*>(0, 0, 0); // types deduced sequence int*, float*, int }
— end example ]
the above means though of parameters specified, deduction doesn't end. parameter pack must expandable argument deduction. it's if explicit arguments given instantiation of template trailing parameter pack. when coupled following:
trailing template arguments can deduced or obtained default template-arguments may omitted list of explicit template-arguments. a trailing template parameter pack not otherwise deduced deduced empty sequence of template arguments. ...
the compiler must match un-deduced arguments empty pack. has nothing deduce from.
as such, attempt plug args...
aaa
cannot possibly match. because type sequence 2 types trailing list (that compiler cannot deduce empty nullptr
). while aaa
expects 2 types.
Comments
Post a Comment