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