函数模板不应被特化
8.37 ID_functionSpecialization
特化的函数模板不参与重载函数的选取,易导致意料之外的错误。
如果某些特殊情况确实需要特化模板,不妨将函数委托给模板类实现,通过特化模板类实现特殊的需求,参见 ID_narrowCast。
示例:
template <class T>
int foo(T) { // #1
return 0;
}
template <class T>
int foo(T*) { // #2
return 1;
}
template <>
int foo<int*>(int*) { // #3, non-compliant, specialization of #1
return 2;
}
int main() {
int* p = nullptr;
cout << foo(p) << '\n'; // What is output?
}
输出 1,特化的函数模板不参与重载函数的选取,所以只会在 #1 和 #2 中选取,foo(p) 与 #2 更贴近,而 #3 是 #1 的特化,所以不会选取 #3,这种情况下 #3 是无效的。
应去除对函数模板的特化,改为普通重载函数:
int foo(int*) { // #3, compliant, safe and brief
return 2;
}
这样例中 main 函数会输出 2。
参考
C++ Core Guidelines T.144
MISRA C++ 2008 14-8-1