如何确定夹心模板将被使用

Ail*_*een 6 c++ templates

我正在学习c ++中的模板,并且发现了以下示例。

据我了解,如果没有匹配的非模板函数,编译器应始终尝试使用最“专业化”的模板,但是在此示例中,第一次调用导致调用函数a(T *)而不是a(int) *)。为什么?为何第二通电话的行为有所不同?

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

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

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

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

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

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

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

结果输出为:

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

我期望它是:

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

Jar*_*d42 6

选择主要的模板过载(因此不需专门化)即可。

一旦使用主模板完成选择,我们将使用专业化(如果有)。

现在,template<> void a<>(int*);只能进行专门化template<typename T> void a(T)(其他版本尚未见)。

并且template<> void b<>(int*);是的专业化template<typename T> void b(T*)(它是更专业的匹配重载)。

请注意,您可以b通过提供模板而不是让编译器推断来选择的特化:

  • template<> void b<>(int*) -> template<typename T> void b(T*) with T=int
  • template<> void b<int>(int*) -> template<typename T> void b(T*) with T=int
  • template<> void b<int*>(int*) -> template<typename T> void b(T) with T=int*

因此对于:

int i;
a(&i); // a<T*> with T=int*, no specialization for a<U*> (U=int) exist -> generic template called
b(&i); // b<T*> with T=int*, specialization for b<U*> (U=int) exists -> specialization called
Run Code Online (Sandbox Code Playgroud)