模板元编程(3):类型选择

模板元编程(3):类型选择
     类型选择是一种编译时的类型计算技术,也就是根据条件判断来匹配对应的类型,功能形如运行时的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    }
;

   最后来看下测试示例
 1 typedef  char     T1;
 2 typedef  short    T2;
 3 typedef  int       T4;
 4 typedef  double  T8;
 5
 6 template  <size_t size >
 7 struct  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
28 template < int  N >
29 struct  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
52 int  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下编译通过。

你可能感兴趣的:(模板元编程(3):类型选择)