正确地专门化函数模板的正确方法

use*_*038 3 c++ templates

我对函数的显式模板特化的语法略感困惑.

假设我有以下内容:

template<class T> 
void f(T t)
{}
Run Code Online (Sandbox Code Playgroud)

我知道,对于明确的专业化,我需要提供template <>,否则我会超载.以下两个编译:

// (a)
template<> 
void f<int>(int t)
{}

//(b)
template<> 
void f(int t)
{}
Run Code Online (Sandbox Code Playgroud)

但是,(a)和(b)之间有什么区别?

T.C*_*.C. 5

如上所述,两者都做同样的事情.模板参数推导用于确定T显式专业化的类型.当您重载功能模板时,"fun"会启动:

template<class T>         //#1
void f(T t)
{}

template<class T>         //#2
void f(T* t)
{}

template<> 
void f<int*>(int* t)      // specializes #1
{}

template<> 
void f(int* t)      // specializes #2, equivalent to void f<int>(int* t)
{}
Run Code Online (Sandbox Code Playgroud)

当您更改订单时,真正的"乐趣"就开始了:

template<class T>         //#1
void f(T t)
{}

template<> 
void f(int* t)      // specializes #1, equivalent to void f<int*>(int* t)
{}

template<class T>         //#2
void f(T* t)
{}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您会得到违反直觉的结果:

int *p;
f(p);              // calls #2, not explicitly specialized #1
Run Code Online (Sandbox Code Playgroud)

这就是为什么通常更好地使用重载而不是函数模板的显式特化.