C++模板正式排序规则

Olu*_*ide 3 c++ templates

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

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

我想要理解这个例子.

编辑

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

template<typename T>
int f(T)
{
    return 1;
}

template<typename T>
int f(T*)
{
    return 2;
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*eas 5

规则有点难以解释而不是使用.如果更专业化的可能实例化的集合是较不专业化的一组可能实例化的严格子集,则该想法是模板比另一模板更专业.

也就是说,每个可以用作更专业化的参数的类型也可以用作较不专业化的参数,并且至少有一种类型可以用于不太专业化的类型,不能用于更专业化的类型.

给出两个模板:

template <typename A> void f( A );   // [1]
template <typename B> void f( B* );  // [2]
Run Code Online (Sandbox Code Playgroud)

要解决的问题是哪一个更通用(即可以采用更多的参数).在标准的整个说明书中被用于合成独特的类型方面做AB,但在一个不太精确的方式,我们可以尝试通过挥手来解决.

假设我们找到一个X匹配第二个模板参数的类型,那么第二个模板的实例化将会是这样的void f( X* )(除了它是一个模板的事实).现在,模板[1]可以用来生成等效函数吗?是的,通过进行A == X*类型扣除.我们可以朝相反方向做吗?假设我们找到了一个类型Y,我们可以用它来实例化第一个模板void f( Y ).第二个模板可以匹配此调用吗?不,仅适用于前一语句可以容纳的指针类型的子集.

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

对于实际示例,f( char* )可以由两个模板匹配,但f( 5 )只能由第一个模板匹配.在合成类型方面进行奇怪解释的原因是单个示例不保证订单,它必须适用于所有类型.合成类型是任何类型的代表.