编译期常量字符串拼接处理

2018-06-27 09:58:12来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

随着C++ 11的语法越来越复杂,功能也越来越强。用泛型+返回类型推导的方法来实现常量字符串的处理,能实现宏实现不了的地方,并且在编译期实现

SO上的牛人太多了,以下是出处

http://stackoverflow.com/questions/15858141/conveniently-declaring-compile-time-strings-in-c/15890335#15890335

1.定义

 1 namespace blog {
 2     typedef long long hash64;
 3     namespace const_expr
 4     {
 5         constexpr hash64 prime = 0x100000001B3ull;
 6         constexpr hash64 basis = 0xCBF29CE484222325ull;
 7     }
 8     constexpr hash64 make_hash_static(char const* str)
 9     {
10         return (*str) ? (*(str + 1)) ? (((*str) * const_expr::prime + const_expr::basis) ^ make_hash_static(str + 1)) : ((*str) * const_expr::prime + const_expr::basis) : 0;
11     }
12 
13     constexpr hash64 operator "" _hash(char const* p, size_t)
14     {
15         return make_hash_static(p);
16     }
17     template<char>using charDummy = char;
18     template <int N>
19     constexpr char at(const char* a) { return a[N]; }
20     template<int... dummy>
21     struct F
22     {
23         const char Name[sizeof...(dummy)+1];
24         const hash64  Hash;
25         const int Length;
26         const int Size;
27 
28         constexpr F(const char* a) : Name{ at<dummy>(a)..., 0 }, Length(sizeof...(dummy)), Size(sizeof...(dummy)+1), Hash(a[0] * const_expr::prime + const_expr::basis){}
29         constexpr F(hash64 h, charDummy<dummy>... a) : Name{ a..., 0 }, Length(sizeof...(dummy)), Size(sizeof...(dummy)+1), Hash(h){}
30         constexpr F(const F& a) : Name{ a.Name[dummy]..., 0 }, Length(a.Length), Size(a.Size), Hash(a.Hash){}
31 
32         template<int... dummyB>
33         constexpr F<dummy..., sizeof...(dummy)+dummyB...> operator + (F<dummyB...> b)const
34         {
35             return{ this->Hash ^ b.Hash,this->Name[dummy]..., b.Name[dummyB]... };
36         }
37         operator const char*()const { return Name; }
38     };
39 
40     template<int I>
41     struct get_string
42     {
43         constexpr static auto g(const char* a) -> decltype(get_string<I - 1>::g(a) + F<0>(a + I))
44         {
45             return get_string<I - 1>::g(a) + F<0>(a + I);
46         }
47     };
48 
49     template<>
50     struct get_string<0>
51     {
52         constexpr static F<0> g(const char* a)
53         {
54             return{ a };
55         }
56     };
57 
58     template<int I>
59     constexpr auto str(const char(&a)[I]) -> decltype(get_string<I - 2>::g(a))
60     {
61         return get_string<I - 2>::g(a);
62     }
63 }

2.使用

 1     constexpr auto s = blog::str("abc")+ blog::str(blog_numb2str(12345678)) + blog::str("edf");
 2     std::cout << s.Name << std::endl;
 3     std::cout << s.Hash << std::endl;
 4     std::cout << s.Length << std::endl;
 5     std::cout << s.Size << std::endl;
 6     using namespace blog;
 7     switch (s.Hash) {
 8     case "abcedf"_hash:
 9         std::cout << "s is " << s.Hash << std::endl;
10         break;
11     case s.Hash + 1:
12         break;
13     case "abc12345678edf"_hash:
14         std::cout << "s is " << s.Name << std::endl;
15         break;
16     }

3.结果

   abc2345678edf

   535462162733975

   14

   15

   s is abc2345678edf

4.优缺点

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:仿《雷霆战机》飞行射击手游开发--项目总览

下一篇:SFINAE与is_base_of