C++模板形式化排序规则

C++ Template Formal Ordering Rules

本文关键字:排序 规则 形式化 C++      更新时间:2023-10-16

我很难理解形式排序规则是如何工作的,如D.Vandevoorde和N.m.Josuttis的《C++模板,完整指南》一书的第12章所述。在本书第188页,作者给出了以下场景,用于决定两个可行的函数模板中哪一个更专业:

根据这两个模板,我们通过替换前面描述的模板参数来合成两个参数类型列表:(A1)(A2*)(其中A1A2是唯一的组合类型)。显然,通过将A2*替换为T,第一个模板相对于第二个参数类型列表的推导是成功的。然而,没有办法使第二模板的T*与第一列表中的非帧间类型A1匹配。因此,我们正式得出结论,第二个模板比第一个模板更专业。

我想了解一下这个例子。

编辑

我相信上面引用的两个功能模板是

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]

要解决的问题是,其中哪一个更为通用(即可以采用更多的参数)。标准中的整个描述是根据用于AB的合成独特类型进行的,但我们可以尝试通过挥手来解决。

假设我们找到了一个与第二个模板参数匹配的类型X,那么第二个模版的实例化将看起来像void f( X* )(除了它是一个模版这一事实之外)。现在,模板[1]可以用来生成一个等价的函数吗?是的,通过在类型推导中设置A == X*。我们能朝相反的方向做吗?假设我们找到一个类型Y,用它可以实例化第一个模板,我们得到void f( Y )。第二个模板可以匹配此调用吗?否,仅对于指针类型的子集,上一条语句可以容纳。

这意味着第二个模板更加专业化,因为对于第二个模版的每个有效实例化,我们也可以实例化第一个模版,但第一个模版的一些实例化不是第二个的有效实例化。

例如,f( char* )可以由两个模板匹配,但f( 5 )只能由第一个模板匹配。根据合成类型进行奇怪解释的原因是,单个示例不能保证顺序,它必须适用于所有类型。合成型是任何型的代表。

我认为作者的观点是,第一个模板中的T既可以与类型a匹配,也可以与指向类型a*的指针匹配,而第二个模板只能与指向类型a*的指针相匹配,因此第二个模版更专业。