支持在枚举编码与字符串形式间转换的c++的枚举模板类(c++17)

工作中经常遇到在枚举编码与字符串形式转换的需求,写一个模板类来实现该功能。

理想情况下,字符串的类型最好自动推导,但尝试用auto function() ->decltype()的方法实现总是提示语法错误无法编译,留待将来解决,现暂用模板参数实现。

  1 #ifndef DEFINITIONWRAP_H
  2 #define DEFINITIONWRAP_H
  3 
  4 #include <string>
  5 #include <vector>
  6 #include <map>
  7 #include <optional>
  8 #include <algorithm>
  9 #include <cassert>
 10 
 11 namespace Framework::Core{
 12 //The template class is used to wrap a enumeration class to help it convert between characters and encoding forms.
 13 //You can define the enumeration class as a struct or class forms, but it must be conform the following conditions:
 14 //The enumeration class must be has a static map class member variable named codeStrings to store the mapping relationship of coding to the string.
 15 //The enumeration class example:
 16 /*
 17 //define:
 18 struct ExampleDefiniation
 19 {
 20     enum Code{
 21         Code1
 22         , Code2
 23     };
 24 
 25     static const std::map<Code, std::wstring> codeStrings;
 26 };
 27 
 28 const std::map<Code, std::wstring> Example::codeStrings{
 29     {Exmaple::Code1, L"CodeString1"}
 30     ,{Example::Code2, L"CodeString2"}
 31 };
 32 using Example = DefinitionWrap<ExampleDefinition, ExampleDefiniation::Code1>;
 33 
 34 //using
 35 auto code1{L"CodeString1"};
 36 auto code2{Example::Definition::Code2};
 37 Exmaple::Definition code1Val{code1};
 38 std::wstring codeStr2{code2};
 39 */
 40 template <typename T, typename T::Code defCode, typename StringType=std::wstring>
 41 class DefinitionWrap
 42 {
 43 public:
 44     using Definition = typename T::Code;
 45 
 46     static std::optional<StringType> toString(const Definition& code) {
 47         const auto it{ T::codeStrings.find(code) };
 48         if (it != T::codeStrings.cend()) {
 49             return it->second;
 50         }
 51         return {};
 52     }
 53 
 54     static std::optional<Definition> toCode(const StringType& str) {
 55         const auto it = std::find_if(T::codeStrings.cbegin(), T::codeStrings.cend(), [str](auto &val) {return val.second == str;});
 56         if (it != T::codeStrings.cend()) {
 57             return it->first;
 58         }
 59         return {};
 60     }
 61     static std::vector<StringType> getDefinitionStrings(void) {
 62         std::vector<StringType> strings;
 63         std::for_each(T::codeStrings.cbegin(), T::codeStrings.cend(), [&](const auto &item){strings.emplace_back(item.second);});
 64         return strings;
 65     }
 66     static std::vector<Definition> getDefinitionCodes(void){
 67         std::vector<Definition> codes;
 68         std::for_each(T::codeStrings.cbegin(), T::codeStrings.cend(), [&](const auto &item){codes.emplace_back(item.first);});
 69         return codes;
 70     }
 71     static bool isValidDefinitionCode(const int code){
 72         auto codes{getDefinitionCodes()};
 73         return std::find_if(codes.begin(), codes.end(), [code](auto i){return static_cast<int>(i)==code;})!=codes.end();
 74     }
 75     static bool isValidDefinitionString(const StringType str){
 76         return static_cast<bool>(toCode(str));
 77     }
 78 
 79     explicit DefinitionWrap(const int& code) {
 80         operator=(code);
 81     }
 82     DefinitionWrap(const Definition& code = defCode) : codeValue(code) {}
 83     DefinitionWrap(const StringType& str) {
 84         operator=(str);
 85     }
 86     DefinitionWrap(const DefinitionWrap& ins) : codeValue(ins.codeValue) {}
 87 
 88     bool operator ==(const DefinitionWrap& ins) const {
 89         return codeValue == ins.codeValue;
 90     }
 91     bool operator ==(const Definition& code) const {
 92         return codeValue == code;
 93     }
 94     bool operator !=(const DefinitionWrap& ins) const {
 95         return codeValue != ins.codeValue;
 96     }
 97     bool operator !=(const Definition& code) const {
 98         return codeValue != code;
 99     }
100     bool operator <(const DefinitionWrap& ins) const {
101         return codeValue<ins.codeValue;
102     }
103 
104     DefinitionWrap &operator=(const Definition& code) {
105         codeValue = code;
106         return *this;
107     }
108     DefinitionWrap &operator=(const StringType &str) {
109         codeValue = toCode(str);
110         assert(codeValue);
111         return *this;
112     }
113     DefinitionWrap &operator=(const int value) {
114         if (isValidDefinitionCode(value))
115         {
116             codeValue = static_cast<Definition>(value);
117         }
118         else
119         {
120             assert(false);
121             codeValue.reset();
122         }
123         return *this;
124     }
125 
126     operator StringType() const {
127         assert(codeValue);
128         return toString(*codeValue).value();
129     }
130     operator Definition() const {
131         assert(codeValue);
132         return codeValue.value();
133     }
134 
135 protected:
136     std::optional<Definition> codeValue{ defCode };
137 };
138 
139 //template <typename T, typename StringType>
140 //decltype(DefinitionWrap::DefinitionStrings) DefinitionWrap<T, StringType>::DefinitionStrings{ T::codeStrings };
141 }
142 
143 #endif // DEFINITIONWRAP_H

 

转载于:https://www.cnblogs.com/thinkway/p/6773382.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,枚举类型和字符串的互相转换是比较常见的需求。下面将分别介绍如何实现这两种转换。 首先,将枚举类型转换字符串。在C语言中,我们可以利用switch语句和枚举类型的取值来实现。如下面的代码所示: ```c enum Fruit { APPLE, BANANA, ORANGE }; const char* fruitToString(enum Fruit fruit) { switch (fruit) { case APPLE: return "apple"; case BANANA: return "banana"; case ORANGE: return "orange"; default: return ""; } } ``` 在这段代码中,我们定义了一个枚举类型`Fruit`,其中包含了三个取值。然后,我们定义了一个函数`fruitToString`,该函数接受一个枚举类型的参数,并返回一个对应的字符串。在函数内部,我们使用了switch语句来根据不同的枚举值返回不同的字符串。 其次,将字符串转换枚举类型。在C语言中,我们可以采用一些方法来实现这个转换。以下是一种常见的方式: ```c enum Fruit stringToFruit(const char* str) { if (strcmp(str, "apple") == 0) { return APPLE; } else if (strcmp(str, "banana") == 0) { return BANANA; } else if (strcmp(str, "orange") == 0) { return ORANGE; } else { return -1; // 表示转换失败 } } ``` 在这个函数中,我们定义了一个名为`stringToFruit`的函数,该函数将一个字符串转换枚举类型。我们使用了`strcmp`函数来比较字符串是否相等,从而确定对应的枚举值。如果字符串无法转换枚举类型,函数返回-1表示转换失败。 总的来说,在C语言中,枚举类型和字符串互相转换并不是很复杂。只要我们熟悉基本的语法和函数,就可以很轻松地实现这些转换

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值