在泛型編程中,很多時候用到類型映射,類型轉換等,比如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.優缺點