跳转到内容

更多 C++ 惯用法/类型选择

来自 Wikibooks,开放世界中的开放书籍

类型选择

[编辑 | 编辑源代码]

根据编译时布尔值或谓词在编译时选择类型。

也称为

[编辑 | 编辑源代码]

能够根据编译时已知的信息做出决策是一个强大的元编程工具。 编译时可以做出的决策之一是决定类型,即类型选择可能根据谓词的结果而有所不同。

例如,考虑一个作为类模板实现的队列抽象数据类型 (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
[编辑 | 编辑源代码]
华夏公益教科书