在阅读this时,我对以下示例感到困惑:
// Example 2: Explicit specialization
//
template<class T> // (a) a base template
void f( T );
template<class T> // (b) a second base template, overloads (a)
void f( T* ); // (function templates can't be partially
// specialized; they overload instead)
template<> // (c) explicit specialization of (b)
void f<>(int*);
// ...
int *p;
f( p ); // calls (c)
此处,(c)
是(b)
的明确专业化。
// Example 3: The Dimov/Abrahams Example
//
template<class T> // (a) same old base template as before
void f( T );
template<> // (c) explicit specialization, this time of (a)
void f<>(int*);
template<class T> // (b) a second base template, overloads (a)
void f( T* );
// ...
int *p;
f( p ); // calls (b)! overload resolution ignores
// specializations and operates on the base
// function templates only
此处(c)
是(a)
的明确专业化。这是为什么?这是因为声明的排序吗?
答案 0 :(得分:12)
是的,这是因为声明的排序。当编译器在第二组中遇到(c)时,唯一定义的专门化模板是(a)。
这就是您在订购模板专业时必须小心的原因。
C ++编程语言详细介绍了这一点(第13.5.1节)。我强烈推荐它。
答案 1 :(得分:10)
这是订单,但它不是仅订单。对于第一个代码,之前定义了两个模板。但是第二次被采取了。
这是因为比较了两个模板,发现(T)
匹配(T*)
匹配的任何类型,但(T*)
与(T)
的所有类型都不匹配火柴。因此,第二个模板更加专业化。无论何时放置显式特化并且这两个模板匹配,模板都会进行比较,而更专业的模板则通过显式特化来关联。这种比较称为“部分排序”。
答案 2 :(得分:8)
标准必须说明以下关于显式专业化声明的相对定位。 [第14.7.3
段]
函数模板的显式特化声明的放置,类模板,类模板的成员函数,类模板的静态数据成员,类模板的成员类,类模板的成员类模板,成员类模板的函数模板,类模板成员模板的成员函数,非模板类成员模板的成员函数, 类模板的成员类的成员函数模板等,以及类模板的部分特化声明的放置,非模板类的成员类模板,类模板的成员类模板等,可以影响是否一个程序是根据显式专业化声明的相对位置及其在翻译单元中的实例化点的相对定位,如上下文所述。写专业时,要注意它的位置;或者使它编纂将是一种试图点燃其自焚的试验。