https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87629
Bug ID: 87629 Summary: function template parameter deduction succeeds but parameter and deduced arg does not match. Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug is present in all gcc versions. Consider the following code: template<class...Args> struct x{ x(void(*)(int)); }; void foo(int); template<class T> void Tfoo(T); template<class...Args> void x_func(x<Args...> a); void test(){ x_func(foo); //does not compile => standard compliant x_func(Tfoo); //compile! template deduction + conversion => not standard compliant } `x_func(Tfoo)` compiles, but this violate this standard rule [\[temp.deduct.call\]/4](http://eel.is/c++draft/temp.deduct#call-4) which states that the deduced function argument type shall match (almost) the type of the argument: In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference: > - If the original P is a reference type, the deduced A (i.e., the type > referred to by the reference) can be more cv-qualified than the transformed A. > - The transformed A can be another pointer or pointer-to-member type that > can be converted to the deduced A via a function pointer conversion and/or > qualification conversion. > - If P is a class and P has the form simple-template-id, then the > transformed A can be a derived class of the deduced A. Likewise, if P is a > pointer to a class of the form simple-template-id, the transformed A can be a > pointer to a derived class pointed to by the deduced A. See also this stackoverflow question:https://stackoverflow.com/q/52845621/5632316