更多 C++ 惯用法/类型选择
外观
根据编译时布尔值或谓词在编译时选择类型。
能够根据编译时已知的信息做出决策是一个强大的元编程工具。 编译时可以做出的决策之一是决定类型,即类型选择可能根据谓词的结果而有所不同。
例如,考虑一个作为类模板实现的队列抽象数据类型 (ADT),它保存 Ts 的静态数组,队列的最大容量作为模板参数传递。 Queue 类还需要存储其中存在的元素数量,从零开始。 这种队列类的可能优化可能是使用不同类型来存储大小。 例如,当队列的最大容量小于 256 时,可以使用无符号字符,如果容量小于 65,536,可以使用无符号短整型来存储大小。 对于更大的队列,使用无符号整型。 类型选择惯用法可用于实现这种编译时决策制定。
实现类型选择惯用法的简单方法是IF 模板。 IF 模板接受三个参数。 第一个参数是编译时布尔条件。 如果布尔条件计算结果为true,则选择传递给 IF 模板的第二个类型,否则选择第三个类型。 类型选择惯用法包含一个主模板和一个部分特化,如下所示。
template <bool, class L, class R>
struct IF // primary template
{
typedef R type;
};
template <class L, class R>
struct IF<true, L, R> // partial specialization
{
typedef L type;
};
IF<false, int, long>::type i; // is equivalent to long i;
IF<true, int, long>::type i; // is equivalent to int i;
我们现在使用类型选择惯用法来实现上面提到的队列大小优化。
template <class T, unsigned int CAPACITY>
class Queue
{
T array[CAPACITY];
typename IF<(CAPACITY <= 256),
unsigned char,
typename IF<(CAPACITY <= 65536),
unsigned short,
unsigned int
>::type
>::type size;
// ...
};
Queue 类模板声明 Ts 的一个数组。 size 数据成员的类型取决于使用IF 模板执行的两个比较的结果。 请注意,这些比较不是在运行时执行,而是在编译时执行。
- Boost.MPL 库
- std::conditional