C++ 模板专业化/部分和完整

C++ Template Specialization / Partial and Full

我试图了解模板部分和完全专业化,并使用以下代码:

#include <iostream>
using namespace std;

//Template in C++is a feature. We write code once and use it for any data type including user defined data types.
//What if we want a different code for a particular data type - Template Specialization
template <class T, class Y>
void fun(T a, Y b)
{
    cout << "The main template fun(): " << a << " " <<  b << endl;
}
//If a specialized version is present, compiler first checks with the specialized version and then the main template.
//Compiler first checks with the most specialized version by matching the passed parameter with the data type(s) specified in a specialized version.
template<>
void fun(const char* a, const char* b)
{
    cout << "Specialized Template for int type: " << a << " " <<  b << endl;
}
//Partial specialization allows to specialize only some arguments of a class template, as opposed to explicit full
template<class T>
void fun(T a, int b)
{
    cout << "Partial Template specialization for int type: " << a << " " << b << endl;
}
int main()
{
    fun<int, int>('a', 10);
    fun< const char*, const char*>("Hello", "Morning");
    fun<float, float>(10.14, 19.89);
}

请注意,在 main 中我指定了数据类型,下面是输出:

The main template fun(): 97 10
Specialized Template for int type: Hello Morning
The main template fun(): 10.14 19.89  

但是当我以下面的方式执行主要代码时:

int main()
{
    fun('a', 10);
    fun("Hello", "Morning");
    fun(10.14, 19.89);
}

这是我得到的输出:

Partial Template specialization for int type: a 10
Specialized Template for int type: Hello Morning
The main template fun(): 10.14 19.89 

那么实际的 C++ 模板部分/完全特化状态是什么——我们是否需要在要调用的模板参数中指定数据类型——在许多网站上我也看到了部分特化的以下签名:

template<class Y, const char*>
void fun(Y a, const char* b)

而不是

template<class Y>
void fun(Y a, const char* b)

与完全专业化类似 - 编写和调用部分/完整模板专用函数的确切方法是什么/class?

评论涵盖了一般原则,但这里有一些具体问题值得回答。首先,引理:函数模板的模板参数不需要与其参数类型相关

template<class T>
T make_1() {return T(1);}
auto v=make_1<std::vector<std::string>>(); // {""}
template<class T,class U>
void f(std::conditional_t<sizeof(T)<sizeof(U),int,long> i);

这就是为什么您的“部分专业化”不适合 fun<int, int>(…) 的原因。模板实参不只是说明如何一个接一个地构建参数列表,而是必须与相关函数模板的 actual 模板实参相匹配。只有其中一个,所以它们不匹配。真正的偏特化仍然使用主模板的模板参数列表;它们只是匹配它的参数列表中的某些模式

同时,

template<class Y, const char*>
void fun(Y a, const char* b)

是有效的,但并不代表你的想法,同样的原因:模板参数列表中的const char*引入了一个unnamed(non-type) const char* 类型的模板参数,因此您必须像

一样使用它
char global;
void g() {fun<char,&global>('a',"foo");}

(没有扣除 Y!),只是完全忽略了 &global