以下代码不能用G ++编译(虽然我相信它应该):
#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);
}
我用GCC 4.4到4.7检查了这个,我得到了模板参数演绎失败。用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’
如果我使用显式模板参数(即foo<5>(bar)
),它编译得很好。如果我使用的代码版本没有typedef
,那么它编译得很好:
#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);
}
是否应该编译失败的代码(即,我犯了一个愚蠢的错误)?
答案 0 :(得分:2)
int foo(typename foo_traits<N>::Function *ptr);
签名使其成为不可抵扣的上下文,因此必须包含模板参数,以便值N
已知,因此指针的类型{{1}也被称为。
您的第二个示例是编译的,因为可以推导出ptr
的签名类型。