C++遍历TypeList(可变模板参数)的简单办法

       这里例举了两种方案,一种是基于C++ 17的constexpr,实现起来更精简。另外一种使用传统的方式,C++ 11就可以用了。

       另外C++11的方案也是一种计算不定参数模板参数个数的方法。

 1 #include <iostream>
 2 #include <string>
 3 
 4 // in C++ 17
 5 #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
 6 
 7 namespace
 8 {
 9     template <typename T, typename... ParamTypes>
10     void printTypesImpl()
11     {
12         std::cout << typeid(T).name() << std::endl;
13 
14         if constexpr (sizeof...(ParamTypes) > 0)
15         {
16             printTypesImpl<ParamTypes...>();
17         }
18     }
19 }
20 
21 template <typename... ParamTypes>
22 void printTypesCpp17()
23 {
24     if constexpr (sizeof...(ParamTypes) > 0)
25     {
26         printTypesImpl<ParamTypes...>();
27     }
28 }
29 #endif
30 
31 namespace
32 {
33     // in C++ 11
34     template <typename T, typename... ParamTypes>
35     struct TPrintVariadicTemplateTypes
36     {
37         enum
38         {
39             Count = TPrintVariadicTemplateTypes<ParamTypes...>::Count + 1
40         };
41 
42         void operator ()()
43         {
44             std::cout << typeid(T).name() << std::endl;
45 
46             TPrintVariadicTemplateTypes<ParamTypes...>()();
47         }
48     };
49 
50     template <typename T>
51     struct TPrintVariadicTemplateTypes<T>
52     {
53         enum
54         {
55             Count = 1
56         };
57 
58         void operator ()()
59         {
60             std::cout << typeid(T).name() << std::endl;
61         }
62     };
63 }
64 
65 template <typename... ParamTypes>
66 void printTypesCpp11()
67 {
68     TPrintVariadicTemplateTypes<ParamTypes...>()();
69 }
70 
71 template <>
72 void printTypesCpp11()
73 {
74 }
75 
76 
77 
78 int main()
79 {
80 #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
81     std::cout << "print by C++ 17" << std::endl;
82     printTypesCpp17<>();
83     printTypesCpp17<int>();
84     printTypesCpp17<int, float, std::string>();
85     printTypesCpp17<bool, char, const char*, wchar_t, std::string, double, decltype(std::cout)>();
86 #endif
87 
88     std::cout << "\nprint by C++ 11" << std::endl;
89     printTypesCpp11<>();
90     printTypesCpp11<int>();
91     printTypesCpp11<int, float, std::string>();
92     printTypesCpp11<bool, char, const char*, wchar_t, std::string, double, decltype(std::cout)>();
93 }

输出:

 1 print by C++ 17
 2 int
 3 int
 4 float
 5 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
 6 bool
 7 char
 8 char const * __ptr64
 9 wchar_t
10 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
11 double
12 class std::basic_ostream<char,struct std::char_traits<char> >
13 
14 print by C++ 11
15 int
16 int
17 float
18 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
19 bool
20 char
21 char const * __ptr64
22 wchar_t
23 class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >
24 double
25 class std::basic_ostream<char,struct std::char_traits<char> >

 

posted @ 2023-08-21 21:34  bodong  阅读(188)  评论(0编辑  收藏  举报