Massive attribute causes deduction of template argument

The following code does not compile with g ++ (although I believe that it should):

#include <iostream> template <unsigned N> struct foo_traits { typedef const char ArrayArg[N]; typedef int Function (ArrayArg *); }; template <unsigned N> int foo (typename foo_traits<N>::Function *ptr) { return ptr(&"good"); } int bar (const char (*x)[5]) { std::cout << *x << "\n"; return 0; } int main () { return foo(bar); } 

I checked this with GCC 4.4 to 4.7, and I am being denied the output of the template argument. C 4.7.1:

 prog.cpp: In function 'int main()': prog.cpp:21:19: error: no matching function for call to 'foo(int (&)(const char (*)[5]))' prog.cpp:21:19: note: candidate is: prog.cpp:10:5: note: template<unsigned int N> int foo(typename foo_traits<N>::Function*) prog.cpp:10:5: note: template argument deduction/substitution failed: prog.cpp:21:19: note: couldn't deduce template parameter 'N' 

If I use an explicit template argument (i.e. foo<5>(bar) ), it compiles fine. If I use a version of code without typedef s, it compiles fine:

 #include <iostream> template <unsigned N> int fixfoo (int (*ptr) (const char (*)[N])) { return ptr(&"good"); } int bar (const char (*x)[5]) { std::cout << *x << "\n"; return 0; } int main () { return fixfoo(bar); } 

Is compilation of bad code required (i.e. I made a stupid mistake)?

0
source share
1 answer
 int foo(typename foo_traits<N>::Function *ptr); 

The signature makes it a non-deductible context, so you must include the template arguments so that the value N known, and therefore the pointer type ptr is also known.

The second example compiles because you can specify the type of signature through bar .

+2
source