模板的特化简单地理解就是明确参数的类型,而不是用 typename , 不管是函数模板,还是类模板,都可以实现特批。其语法为:template <> xxx,模板参数是空的。
如下最简单的一个函数模板特化:
- #include
- #include
- #include
-
- template <typename T>
- void func(T a);
-
- template<>
- void func(int value)
- {
- printf("type of T is: int, value = %d\n", value);
- }
-
- int main()
- {
- int value = 10;
- func(value);
-
- return 0;
- }
首先是声明了一个函数模板:
- template <typename T>
- void func(T a);
接下来就是特化这个函数模板,特化的参数类型就是 int 类型:
- template<>
- void func(int value)
- {
- printf("type of T is: int, value = %d\n", value);
- }

假如我们使用 func(10.0)
- #include
- #include
- #include
-
- template <typename T>
- void func(T a);
-
- template<>
- void func(int value)
- {
- printf("type of T is: int, value = %d\n", value);
- }
-
- int main()
- {
- int value = 10;
- func(value);
-
- func(10.0);
- return 0;
- }
则是编译错误的,提示我们没有实现对应类型 double 的模板:

因为我们上面只是声明了一个函数模板,同时特化了一个 int 类型的模板,所以这样只能使用特化的那个版本。那要用其他类型版本的,该如何操作呢?其实就是要声明时同时定义就可以:
- #include
- #include
- #include
-
- template <typename T>
- void func(T a)
- {
- printf("type of T is: %s\n", typeid(T).name());
- }
-
- template<>
- void func(int value)
- {
- printf("type of T is: int, value = %d\n", value);
- }
-
- int main()
- {
- int value = 10;
- func(value);
-
- func(10.0);
- return 0;
- }
只是把声明改成了实现:
- template <typename T>
- void func(T a)
- {
- printf("type of T is: %s\n", typeid(T).name());
- }
实现使用时,int 类型参数使用了特化版本的函数,而 double 则使用普通版本的函数:
我们知道,模板只有在使用的时候才会生成对应类型的代码,如果只是声明或定义时,是不会生成相应代码的;而这个特化的模板是否有相应类型的代码呢?有如下代码:
- #include
- #include
- #include
-
- template <typename T>
- void func(T a)
- {
- printf("type of T is: %s\n", typeid(T).name());
- }
-
- template<>
- void func(int value)
- {
- printf("type of T is: int, value = %d\n", value);
- }
-
- int main()
- {
- int value = 10;
- func(value);
-
- return 0;
- }
可以看到只有一个特化出来对应的 int 版本的代码。如果多加一行代码:func(10.0) ,结果会是什么样的呢?

可以看到多了一个 double 类型的模板代码。
类模板的特化跟函数模板的特化相似的。
- #include
- #include
-
- template <typename T>
- class S;
-
- template<>
- class S<int>
- {
- public:
- void msg()
- {
- printf("fully specialized (S
::msg())\n" ); - }
- };
-
-
- int main()
- {
- S<int> test1;
- test1.msg();
- // S
test2; //这里若要正常使用,则上面的S声明必须要实现,因为S没有void版本的特化。 - // test2.msg();
- return 0;
- }
代码里只是声明了类模板 S,同时特化了 int 类型的类模板,正如注释里说的要想使用 S