有多个与函数调用的自变量列表匹配的函数模板可用。 C++ 定义了函数模板的部分排序以指定应调用的函数。 由于有一些模板可能会视为专用化程度相同,因此排序只是部分的。
编译器从可能的匹配项中选择可用的专用化程度最高的函数模板。 例如,如果一个函数模板采用 T
类型,而另一个采用 T*
的函数模板可用,则称 T*
版本的专用化程度更高。 只要参数是指针类型,它就优于泛型 T
版本,即使两者都是允许的匹配项。
通过以下过程可确定一个函数模板候选项是否更加专用化:
考虑两个函数模板:
T1
和T2
。将
T1
中的参数替换为假想的唯一类型X
。当
T1
中存在参数列表时,查看T2
是否为该参数列表的有效模板。 忽略任何隐式转换。对
T1
和T2
执行相反的过程。如果一个模板是另一个模板的有效模板参数列表,但反之不成立,则认为该模板的专用化程度不如另一个模板。 如果通过使用上一步,两个模板为彼此形成有效的参数,那么它们被视为同等专用化,并且尝试使用它们时会导致调用不明确。
使用以下规则:
针对特定类型的模板的专用化程度高于采用泛型类型参数的模板。
仅采用
T*
的模板的专用化程度比仅采用T
的模板更高,因为假设类型X*
是T
模板参数的有效参数,但X
不是T*
模板参数的有效参数。const T
比T
专用化程度更高,因为const X
是T
模板参数的有效参数,但X
不是const T
模板参数的有效参数。const T*
比T*
专用化程度更高,因为const X*
是T*
模板参数的有效参数,但X*
不是const T*
模板参数的有效参数。
示例
以下示例按照标准中的规定运行:
// partial_ordering_of_function_templates.cpp
// compile with: /EHsc
#include <iostream>
template <class T> void f(T) {
printf_s("Less specialized function called\n");
}
template <class T> void f(T*) {
printf_s("More specialized function called\n");
}
template <class T> void f(const T*) {
printf_s("Even more specialized function for const T*\n");
}
int main() {
int i =0;
const int j = 0;
int *pi = &i;
const int *cpi = &j;
f(i); // Calls less specialized function.
f(pi); // Calls more specialized function.
f(cpi); // Calls even more specialized function.
// Without partial ordering, these calls would be ambiguous.
}
输出
Less specialized function called
More specialized function called
Even more specialized function for const T*