我很难理解 D. Vandevoorde 和 N. M. Josuttis 所著的《C++ 模板完整指南》一书第 12 章中描述的正式排序规则的工作原理。在本书第 188 页,作者给出了以下场景,用于确定两个可行的函数模板中哪一个更专业:
从这两个模板中,我们通过替换前面描述的模板参数来合成两个参数类型列表:(A1)
and (A2*)
(where A1
and A2
是独特的组成类型)。显然,通过替换,第一个模板对第二个参数类型列表的推导成功了A2*
for T
。然而,没有办法使T*
第二个模板的匹配非指针类型A1
在第一个列表中。因此,我们正式得出结论,第二个模板比第一个模板更专业。
我想了解一下这个例子。
Edit
我相信上面引用中提到的两个函数模板是
template<typename T>
int f(T)
{
return 1;
}
template<typename T>
int f(T*)
{
return 2;
}
这些规则解释起来比使用起来要困难一些。这个想法是,如果更专业化的模板的可能实例化集合是不太专业化模板的可能实例化集合的严格子集,则一个模板比另一个模板更专业化。
也就是说,每一种可以用作更专业的参数的类型也可以用作不太专业的参数,并且至少有一种类型可以与不太专业的类型一起使用,但不能与更专业的类型一起使用。
给定两个模板:
template <typename A> void f( A ); // [1]
template <typename B> void f( B* ); // [2]
要解决的问题是哪一个更generic(即可以采用更多数量的参数)。标准中的整个描述是根据用于的合成独特类型来完成的A
and B
,但我们可以尝试以不太精确的方式通过挥手来解决。
假设我们找到一个类型X
匹配第二个模板参数,那么第二个模板的实例化将如下所示void f( X* )
(除了它是一个模板这一事实)。现在,模板 [1] 可以用来生成等效的函数吗?是的,通过制作A == X*
在类型推导中。我们可以反方向做吗?假设我们找到一个类型Y
我们可以用它实例化第一个模板,我们得到void f( Y )
。第二个模板可以匹配这个调用吗?不,仅适用于以下类型的子集pointers前面的说法可以成立。
这意味着第二个模板更专门,因为对于第二个模板的每个有效实例化,我们也可以实例化第一个模板,但是第一个模板的某些实例化不是第二个模板的有效实例化。
举一个实际的例子,f( char* )
两个模板都可以匹配,但是f( 5 )
只能与第一个匹配。关于合成类型的奇怪解释的原因是单个示例不能保证顺序,它必须保持all类型。合成型的代表是any type.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)