与完全模板专业化相反,部分模板专业化允许引入带有固定现有模板参数的模板。部分模板专门化仅适用于模板类/结构:
// 常见情况: template<typename T, typename U> struct S { T t_val; U u_val; }; // 当第一个模板参数固定为int时的特殊情况 template<typename V> struct S<int, V> { double another_value; int foo(double arg) {// 做点什么} };
如上所示,部分模板专业化可能会引入完全不同的数据和函数成员集。
实例化部分专用的模板时,将选择最合适的专用。例如,让我们定义一个模板和两个部分专业化:
template<typename T, typename U, typename V> struct S { static void foo() { std::cout << "General case\n"; } }; template<typename U, typename V> struct S<int, U, V> { static void foo() { std::cout << "T = int\n"; } }; template<typename V> struct S<int, double, V> { static void foo() { std::cout << "T = int, U = double\n"; } };
现在,以下调用:
S<std::string, int, double>::foo(); S<int, float, std::string>::foo(); S<int, double, std::string>::foo();
将打印
General case T = int T = int, U = double
功能模板可能仅是完全专用的:
template<typename T, typename U> void foo(T t, U u) { std::cout << "一般情况: " << t << " " << u << std::endl; } // 好。 template<> void foo<int, int>(int a1, int a2) { std::cout << "两个整数: " << a1 << " " << a2 << std::endl; } void invoke_foo() { foo(1, 2.1); // Prints "一般情况: 1 2.1" foo(1,2); // Prints "两个整数: 1 2" } // 编译错误:不允许部分函数专门化。 template<typename U> void foo<std::string, U>(std::string t, U u) { std::cout << "一般情况: " << t << " " << u << std::endl; }