在泛型編程中,很多時候用到類型映射,類型轉換等,比如int2type,type2type.
在有些時候可能需要將常量靜態字符串作為類型,也就是string2type.
//https://github.com/ColinH/PEGTL 這個庫將泛型大量用到了字符串處理中,其中就有string2type.
1.定義
1 namespace blog 2 { 3 namespace internal{ 4 template< std::size_t N, std::size_t M > 5 constexpr char string_at(const char(&c)[M]) noexcept 6 { 7 static_assert(M <= 101, "String longer than 100 (excluding terminating \\0)!"); 8 return (N < M) ? c[N] : 0; 9 } 10 11 template< char ... Cs > struct string; 12 13 template<> struct string<> {}; 14 15 template< char ... Cs > 16 struct string 17 { 18 static constexpr char const value[sizeof...(Cs)+1] = { Cs...,'\0' }; 19 }; 20 template<char... C> 21 constexpr char const string<C...>::value[sizeof...(C)+1]; 22 } 23 template< char ... Cs > struct string : internal::string< Cs ... > {}; 24 25 namespace internal 26 { 27 template< typename, char ... > 28 struct string_builder; 29 template< typename T > 30 struct string_builder< T > { using type = T; }; 31 template< template< char ... > class S, char ... Hs, char C, char ... Cs > 32 struct string_builder< S< Hs ... >, C, Cs ... > 33 : std::conditional< C == '\0', 34 string_builder< S< Hs ... > >, 35 string_builder< S< Hs ..., C >, Cs ... > >::type 36 { }; 37 } 38 }
2.實現
1 #define MTL_INTERNAL_STRING_10(n,x) \ 2 blog::internal::string_at< n##0 >( x ), \ 3 blog::internal::string_at< n##1 >( x ), \ 4 blog::internal::string_at< n##2 >( x ), \ 5 blog::internal::string_at< n##3 >( x ), \ 6 blog::internal::string_at< n##4 >( x ), \ 7 blog::internal::string_at< n##5 >( x ), \ 8 blog::internal::string_at< n##6 >( x ), \ 9 blog::internal::string_at< n##7 >( x ), \ 10 blog::internal::string_at< n##8 >( x ), \ 11 blog::internal::string_at< n##9 >( x ) 12 #define blog_str2type(x) \ 13 blog::internal::string_builder< blog::internal::string<>, \ 14 MTL_INTERNAL_STRING_10(,x), \ 15 MTL_INTERNAL_STRING_10(1,x), \ 16 MTL_INTERNAL_STRING_10(2,x), \ 17 MTL_INTERNAL_STRING_10(3,x), \ 18 MTL_INTERNAL_STRING_10(4,x), \ 19 MTL_INTERNAL_STRING_10(5,x), \ 20 MTL_INTERNAL_STRING_10(6,x), \ 21 MTL_INTERNAL_STRING_10(7,x), \ 22 MTL_INTERNAL_STRING_10(8,x), \ 23 MTL_INTERNAL_STRING_10(9,x) >::type
3.使用
1 typedef blog_str2type("abcdefg") abcdefg; 2 std::cout << abcdefg::value << std::endl;
4.結果
abcdefg
5.優缺點