为什么在以下示例中无法从T
的签名中推断出fn
?
template<int I>
struct Class {
template<typename T>
Class &operator <<( void (*)(const Class<I> &, const T &) ) { return *this; }
};
struct Ot { };
template<int I>
void fn(const Class<I> &, const Ot &) { }
int main() {
Class<1>() << fn;
}
相反,以下不将operator<<
作为常规成员的示例是合法的:
template<int I>
struct Class {
Class &operator <<( void (*)(const Class<I> &) ) { return *this; }
};
struct Ot { };
template<int I>
void fn(const Class<I> &) { }
int main() {
Class<1>() << fn;
}
答案 0 :(得分:2)
因为就像您使用Class<1>
而不是Class
一样,您还必须将模板参数提供给功能模板fn
:
Class<1>() << fn<1>;
此外,您可能希望从operator <<
:
template<typename T>
Class & operator <<( void (*)(const Class<I> &, const T &) ) { return *this; }
^
答案 1 :(得分:0)
归结为功能模板的模板参数可以是显式指定的,也可以从传递给函数的参数中推导出来。
在您的示例中,编译器无法确定fn
的模板参数,因为在Class<1>::operator<<()
的调用中没有传递参数。因此,您必须明确指定它:fn<1>
(或任何您想要的)。完成此操作后,fn
的类型是明确的,编译器可以从T
的第二个参数类型(即fn&lt; 1&gt;)中推断出Class<1>::operator()
的类型。
换句话说,fn
的类型并不清楚。你可以通过fn&lt; 2&gt;到Class&lt; 1&gt; :: operator&lt;&lt;()。请考虑以下代码:
Class<1> << fn<2>; // fn<2> is not fn<1>
Class<1> << fn<1>; // OK too, of course
Class<1> << fn; // error! fn<?>