C++不同的模板方法调用同一个变量

zle*_*nyk 17 c++ templates template-specialization

有人可以解释为什么一次使用方法c(T*)和下一次d<>(int*)?方法cd我似乎完全相同,我无法弄清楚为什么不是同一类型的方法调用.

#include <iostream>
using namespace std;

template<typename T>
void c(T){ cout <<"(T)" << endl; }

template<>
void c<>(int*){ cout <<"(int*)" << endl; }

template<typename T>
void c(T*){ cout <<"(T*)" << endl; }

template<typename T>
void d(T){ cout <<"(T)" << endl; }

template<typename T>
void d(T*){ cout <<"(T*)" << endl; }

template<>
void d<>(int*){ cout <<"(int*)" << endl; }

int main(){
    int i;
    c(&i);
    d(&i);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

(T*)
(int*)
Run Code Online (Sandbox Code Playgroud)

Mat*_* M. 18

你只是偶然发现了一个丑陋的C++部分.

在编译期间,重载决策过程是关于为当前代码找到最佳过载.它在查找阶段选择的一组函数和函数模板上执行,旨在识别一个(并且只有一个)优于其他的重载.

对于功能模板,它们分为两组:

  • "基础"功能模板
  • 专业的功能模板

并且重载解析过程有两个步骤:

  1. 选择常规函数和"基本"函数模板中的最佳匹配
  2. 如果在步骤1中选择了"基本"功能模板,请选择最佳专业化(如果有匹配,否则使用"基础")

在您的两个例子,最好的"基地"的功能是c(T*)d(T*),所以这是不同的第二步.为什么?

因为,要成为函数模板的特化,必须首先声明所述函数模板.

从而:

  • c<>(int*) 是一个专业化的 c(T)
  • d<>(int*) 是一个专业化的 d(T*)

因此,当c(T*)在步骤1中选择时,那么在d(T*)挑选时没有更好的专业化,d<>(int*)是更好的专业化.

因为这很棘手,专家的建议......不是使用功能模板专业化.它只是与功能模板重载奇怪地混合在一起.


Con*_*tor 15

template <typename T>
void c(T);      // 1: function template

template <>
void c<>(int*); // 2: specialization of 1

template<typename T>
void c(T*);     // 3: overload of 1

template<typename T>
void d(T);      // 4: function template

template<typename T>
void d(T*);     // 5: overload of 4

template<>
void d<>(int*); // 6: specialization of 5

// ...

int i;

c(&i);          // 3 is more appropriate overload than 1

d(&i);          // 5 is more appropriate overload than 4
                // and it has the suitable specialization 6
Run Code Online (Sandbox Code Playgroud)

图:

                    c        d
                   / \      / \
overloads         1  (3)   4  (5)   |
                  |            |    |  priority
specializations   2           (6)   V
Run Code Online (Sandbox Code Playgroud)