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> >