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.

[temp.arg.explicit/9]

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:

[temp.arg.explicit/3]

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

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -