C++ Template 第6-8章笔记
boost之array,效率与优雅之正交点

编译期之常量区间的实现

皮贝贝 posted @ 2008年11月14日 05:50 in 岁月舍利 with tags 常量区间 模板 , 1729 阅读

      有时候我们指定一系列区间, 然后由给定值来判定在某个区间之内。初学c语言必定会遇到这样一个问题: 给定学生成绩,来判定是否在A,B,C,D所属之区间内。只不过我们现在研究的是编译期之此等动作。

      从底层基本组件实现起, 一个区间实现:

  1.  
  2. // 常量区间
  3. template <int N1, int N2>
  4. struct Rect
  5. {
  6.         enum { Begin = N1 };
  7.         enum { End   = N2 };
  8. };
  9.  

为实现区间之判断功能,作为一个动作构件:

  1.  
  2. // 检测 一个值是否在某个区间
  3. template <int N, class RectType>
  4. struct InRect
  5. {
  6.         enum { Value = ( N >= RectType::Begin && N < RectType::End ) };
  7. };

为实现区间之任意个数,选用Loki之TypeList辅佐之:

  1.  
  2. // 检测 常量区间
  3. template <int N, class TList, template <int, class> class InRect>
  4. struct CheckRect {};
  5.  
  6. template <int N, class Head, class Tail,
  7.          template <int, class> class InPolicy>
  8. struct CheckRect <N, TypeList <Head, Tail>, InPolicy>
  9. {
  10.         typedef typename SelectType < InPolicy<N, Head>::Value,
  11.                                 Head,
  12.                                 typename CheckRect <N, Tail, InPolicy> ::Result
  13.                         > ::Result     
  14.                 Result;
  15. };
  16.  
  17. template <int N, template <int, class> class InPolicy>
  18. struct CheckRect <N, NullType, InPolicy>
  19. {
  20.         typedef EmptyType Result;
  21. };

至此,工作已就,测试代码如下:

  1.  
  2. #define MakeRect( a, b )     Rect <a, b>
  3.  
  4. int main()
  5. {
  6.         typedef CheckRect < 12, TYPELIST_2( MakeRect(1,4), MakeRect(5,19) ), InRect> ::Result My12Rect;
  7.  
  8.         cout << My12Rect ::Begin << endl;
  9.         cout << My12Rect ::End << endl;
  10.         return 0;
  11. }

    测试代码中,定义了宏 MakeRect 是因C++编译器的宏只认识逗号  (‘,’),比如 TYPELIST_1( Rect <1,2> ) ,编译器的处理是认为TYPELIST_1的参数是 Rect <1 2>这两个,因此可能会提示参数过多的警告。

上述只是一初步设想的粗糙版本,尚有多处改进:

        1. Default 之接口一致性

        2. 更优雅的适应或构造 类 switch case 的语法结构中。

        3. 扩展性。如可以自由的后续添加分派动作。

由于上述缺点,尚未能应用于应用中,日后改进。

  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter