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
,
我试图了解模板部分和完全专业化,并使用以下代码:
#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
,