c++ - 专门化函数重载的规则

标签 c++ overloading template-specialization

考虑代码:

#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, and A 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/

相关文章:

c++ - () 仿函数后的括号而不是函数指针?

c++ - 专用结构/类中未识别的数据成员

scala - 在 Scala 中,有没有办法让两个重载方法仅在隐式是否可用方面有所不同?

c++ - Eclipse CDT : Symbol 'cout' could not be resolved

c++ - 如何从预处理程序#if指令调用constexpr函数?

c++ - 如果我还需要使用 ODE,我应该从 Eigen 切换到 MTL4 吗?

c++重载[]以打印链表的第n项

java - 抽象泛型类的不同实现

c++ - 如何专门化 T 的特征类以及 T 的所有后代

c++ - EnterCriticalSection死锁