特化

特化即是为以有的模板参数进行特殊化指定, 根据特化的范围和对象, 可以分为全特化/偏特化, 类特化/函数特化.

全特化

对一个特定参数集合自定义当前模板, 类模板和函数模板都可以全特化. 全特化的模板参数列表应当为空, 并在模板实参中一一指定.

1
2
3
4
5
6
7
8
9
10
11
12

template<typename T1, typename T2>
class A {};

template<>
class A<int, double> {};

template<typename T1, typename T2>
void foo() {};

template<>
void foo<int, double>() {};

偏特化

偏特化是给自定义一个参数集合的模板, 偏特化后的模板需要进一步的实例化才能形成确定的签名. 函数模板是不能进行偏特化的, 可以通过重载来代替偏特化的需要.

1
2
3
4
5
6

template<typename T>
class A {};

template<>
class A<int> {};

泛型约束

在C#中我们可以通过where来进行泛型约束, 指定接口, 基类或要求泛型类型为引用, 值或非托管类型. 在C++中我们可以用enable_if+特化来实现指定基类的功能.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Base {};
class Derived : public Base {};

template <typename T, typename Enable = void>
class Foo {
public:
static void f() {
std::cout << "Default" << std::endl;
}
};

template <typename T>
class Foo<T, typename std::enable_if<std::is_base_of<Base, T>::value>::type> {
public:
static void f() {
std::cout << "Base" << std::endl;
}
};

int main() {
Foo<Derived>::f();
}