在下面的例子中为什么不能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;
}
Run Code Online (Sandbox Code Playgroud)
相比之下,以下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;
}
Run Code Online (Sandbox Code Playgroud)
归根结底,函数模板的模板参数可以显式指定,也可以从传递给函数的参数中推导出来。
在您的示例中,编译器无法确定 的模板参数,fn
因为在对 的调用中没有参数传递给它Class<1>::operator<<()
。因此,您必须明确指定它:(fn<1>
或您想要的任何内容)。一旦完成此操作,并且的类型明确,编译器就可以推导出from的第二个参数类型(即 fn<1>)fn
的类型。T
Class<1>::operator()
换句话说,类型fn
不清楚。您可以将 fn<2> 传递给 Class<1>::operator<<()。考虑这段代码:
Class<1> << fn<2>; // fn<2> is not fn<1>
Class<1> << fn<1>; // OK too, of course
Class<1> << fn; // error! fn<?>
Run Code Online (Sandbox Code Playgroud)