随笔-88  评论-224  文章-23  trackbacks-0
     类型选择是一种编译时的类型计算技术,也就是根据条件判断来匹配对应的类型,功能形如运行时的if else和switch case控制结构。在这里仿真运行时的条件语句,实现了类型选择,包括if单分支、if多分支和switch case三种结构,关于其原理及细节就不多讲了,直接看如下代码
  (1)if单分支
 1    template<bool b,typename T,typename U>
 2    struct if_then_else
 3    {
 4        typedef T type;
 5    }
;
 6    template<typename T,typename U>
 7    struct if_then_else<false,T,U>
 8    {
 9        typedef U type;
10    }
;
  (2)if多分支
 1    template<typename T> struct if_true;
 2    struct if_false;
 3
 4    template<bool b>
 5    struct if_
 6    {
 7        template<typename T>
 8        struct then : if_then_else<b,if_true<T>,if_false>::type
 9        {
10        }
;
11    }
;
12
13    template<typename T>
14    struct if_true
15    {
16        template<bool b>
17        struct elif_
18        {
19            template<typename U>
20            struct then : if_true<T>
21            {
22            }
;
23        }
;
24        template<typename V>
25        struct else_
26        {
27            typedef T type;
28        }
;
29    }
;
30
31    struct if_false
32    {
33        template<bool b>
34        struct elif_ : if_<b>
35        {
36        }
;
37        template<typename T>
38        struct else_
39        {
40            typedef T type;
41        }
;
42    }
;
  (3)switch case
 1    template<typename T> struct case_true;
 2    template<int N> struct case_false;
 3
 4    template<int M>
 5    struct switch_
 6    {
 7        template<int N>
 8        struct case_
 9        {
10            template<typename T>
11            struct then : if_then_else<M==N,case_true<T>,case_false<M> >::type
12            {
13            }
;
14        }
;
15    }
;
16    
17    template<typename T>
18    struct case_true
19    {
20        template<int N>
21        struct case_
22        {
23            template<typename U>
24            struct then : case_true<T>
25            {
26            }
;
27        }
;
28        template<typename V>
29        struct default_
30        {
31            typedef T type;
32        }
;
33    }
;
34
35    template<int M>
36    struct case_false : switch_<M>
37    {
38        template<typename U>
39        struct default_
40        {
41            typedef U type;
42        }
;
43    }
;

   最后来看下测试示例
 1typedef char    T1;
 2typedef short   T2;
 3typedef int      T4;
 4typedef double T8;
 5
 6template <size_t size>
 7struct if_elif_else
 8{
 9    typedef typename if_<
10        (sizeof(T1) == size)
11    >::template then<
12        T1
13    >::template elif_<
14        (sizeof(T2) == size)
15    >::template then<
16        T2
17    >::template elif_<
18        (sizeof(T4) == size)
19    >::template then<
20        T4
21    >::template elif_<
22        (sizeof(T8) == size)
23    >::template then<
24        T8
25    >::template else_<void>::type type;
26}
;
27
28template<int N>
29struct switch_case
30{
31    typedef typename switch_<
32        N
33    >::template case_<
34        sizeof(T1)
35    >::template then<
36        T1
37    >::template case_<
38        sizeof(T2)
39    >::template then<
40        T2
41    >::template case_<
42        sizeof(T4)
43    >::template then<
44        T4
45    >::template case_<
46        sizeof(T8)
47    >::template then<
48        T8
49    >::template default_<void>::type type;
50}
;
51
52int main()
53{
54    BOOST_MPL_ASSERT((boost::is_same<typename if_then_else<true,T1,T2>::type,T1>));
55    BOOST_MPL_ASSERT((boost::is_same<typename if_then_else<false,T1,T2>::type,T2>));
56
57    BOOST_MPL_ASSERT((boost::is_same<typename if_elif_else<1>::type,T1>));
58    BOOST_MPL_ASSERT((boost::is_same<typename if_elif_else<2>::type,T2>));
59    BOOST_MPL_ASSERT((boost::is_same<typename if_elif_else<4>::type,T4>));
60    BOOST_MPL_ASSERT((boost::is_same<typename if_elif_else<8>::type,T8>));
61    BOOST_MPL_ASSERT((boost::is_same<typename if_elif_else<10>::type,void>));
62
63    BOOST_MPL_ASSERT((boost::is_same<typename switch_case<1>::type,T1>));
64    BOOST_MPL_ASSERT((boost::is_same<typename switch_case<2>::type,T2>));
65    BOOST_MPL_ASSERT((boost::is_same<typename switch_case<4>::type,T4>));
66    BOOST_MPL_ASSERT((boost::is_same<typename switch_case<8>::type,T8>));
67    BOOST_MPL_ASSERT((boost::is_same<typename switch_case<10>::type,void>));
68
69    return 0;
70}
   以上所有代码在vc2008和gcc4.6下编译通过。
posted on 2012-06-06 13:49 春秋十二月 阅读(1445) 评论(1)  编辑 收藏 引用 所属分类: C/C++

评论:
# re: 模板技术与应用(2): 类型选择 2012-06-06 14:14 | 华夏之火
第一次看到这些神码时,很激动。这么长时间过去了,现实中还真不容易找到它们的应用场合  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理