模板参数推导在这里很有效,因为对于函数模板,随后的模板参数可以由函数参数推导出来。在这种情况下,可以从函数参数u
推导出模板参数U
。请注意,对于类模板,如您预期的那样,默认模板参数之后的后续模板参数应具有默认模板参数或模板参数包。
$14.1/11 Template parameters [temp.param]:
如果一个类模板,可变模板,或 别名模板的模板参数具有默认模板参数的,每个随后的 模板参数应由具有缺省模板的参数 提供或作为模板参数包。如果 主要类模板,主要变量模板或别名模板 的模板参数是模板参数包,则它应该是最后一个模板参数。 函数模板的模板参数包不能被其他模板参数跟在 之后,除非该模板参数可以是从函数 模板的参数类型列表([dcl.fct])推导的 ,或者具有默认参数([temp.deduct])。 没有默认参数的扣减指南模板([temp.deduct.guide])的模板 参数应从扣除指南模板的 参数类型列表中扣除。 [示例:
template<class T1 = int, class T2> class B; // error
// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { } // error
template<class... T, class U> void g() { } // error
- 结束举例]
你可以试着让U
undeducible,看看会发生什么:
template <bool T=true, class U> //"default" from LEFT-most parameter
void f(){
if(T){ cout<<true;}
else cout<<false;
}
int main() {
f(); // Fail. Can't deduce U.
f<true>(); // Fail. Can't deduce U.
f<true, int>(); // Fine. T=true, U=int.
return 0;
}
注意你必须明确地指定所有的模板参数使代码工作,这使得默认的模板参数完全没有意义。如果要使f()
或f<true>()
正常工作,则还需要将U
也设为默认模板参数(或使其成为模板参数包)。
template <bool T=true, class U=int>
void f(){
if(T){ cout<<true;}
else cout<<false;
}
int main() {
f(); // Fine. T=true, U=int
f<false>(); // Fine. T=false, U=int
f<false, char>(); // Fine. T=false, U=char
return 0;
}