考虑代码:
#include <iostream>
template <typename T>
void f(T)
{
std::cout << "Version 1" << std::endl;
}
template <typename T>
void f(T *)
{
std::cout << "Version 2" << std::endl;
}
template <>
void f<>(int *)
{
std::cout << "Version 3" << std::endl;
}
int main()
{
int *p = nullptr;
f(p);
return 0;
}
此代码将输出版本3
。发生的情况是,函数重载规则查看 void f 的前两个版本(第三个版本是专门化的,不参与重载),并确定第二个版本是更好的版本。一旦做出决定,我们就会看看第二个版本是否存在任何特化。有,而且我们使用它。
那么,我的问题是:编译器如何知道我的显式特化是第二个重载的特化,而不是第一个重载的特化?我没有向它提供模板参数以供其做出选择。决定专门化哪个函数是否遵循与决定调用哪个重载(如果它正在调用该函数)类似/相同的规则?这会有一定道理...
最佳答案
template_argument_deduction#Explicit_instantiation中有这个例子
Template argument deduction is used in explicit instantiations, explicit specializations, and those friend declarations where the declarator-id happens to refer to a specialization of a function template (for example,
friend ostream& operator<< <>
(...)), if not all template arguments are explicitly specified or defaulted, template argument deduction is used to determine which template's specialization is referred to.
P
is the type of the function template that is being considered as a potential match, andA
is the function type from the declaration. If there are no matches or more than one match (after partial ordering), the function declaration is ill-formed:template<class X> void f(X a); // 1st template f template<class X> void f(X* a); // 2nd template f template<> void f<>(int* a) { } // explicit specialization of f // P1 = void(X), A1 = void(int*): deduced X = int*, f<int*>(int*) // P2 = void(X*), A2 = void(int*): deduced X = int, f<int>(int*) // f<int*>(int*) and f<int>(int*) are then submitted to partial ordering // which selects f<int>(int*) as the more specialized template
关于c++ - 专门化函数重载的规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60443031/