函数模板的部分排序 (C++)

有多个与函数调用的自变量列表匹配的函数模板可用。 C++ 定义了函数模板的部分排序以指定应调用的函数。 由于有一些模板可能会视为专用化程度相同,因此排序只是部分的。

编译器从可能的匹配项中选择可用的专用化程度最高的函数模板。 例如,如果一个函数模板采用 T 类型,而另一个采用 T* 的函数模板可用,则称 T* 版本的专用化程度更高。 只要参数是指针类型,它就优于泛型 T 版本,即使两者都是允许的匹配项。

通过以下过程可确定一个函数模板候选项是否更加专用化:

  1. 考虑两个函数模板:T1T2

  2. T1 中的参数替换为假想的唯一类型 X

  3. T1 中存在参数列表时,查看 T2 是否为该参数列表的有效模板。 忽略任何隐式转换。

  4. T1T2 执行相反的过程。

  5. 如果一个模板是另一个模板的有效模板参数列表,但反之不成立,则认为该模板的专用化程度不如另一个模板。 如果通过使用上一步,两个模板为彼此形成有效的参数,那么它们被视为同等专用化,并且尝试使用它们时会导致调用不明确。

  6. 使用以下规则:

    1. 针对特定类型的模板的专用化程度高于采用泛型类型参数的模板。

    2. 仅采用 T* 的模板的专用化程度比仅采用 T 的模板更高,因为假设类型 X*T 模板参数的有效参数,但 X 不是 T* 模板参数的有效参数。

    3. const TT 专用化程度更高,因为 const XT 模板参数的有效参数,但 X 不是 const T 模板参数的有效参数。

    4. 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*

另请参阅

函数模板