在 C 中,枚举提供了一种便捷的方式来表示一组命名常量。但是,当打印枚举值时,默认行为是显示其数字表示形式。
假设我们有一个像这样的枚举:
enum Errors { ErrorA = 0, ErrorB, ErrorC, };
如果我们尝试使用打印枚举值std::cout:
Errors anError = ErrorA; std::cout << anError; // 0 will be printed
我们将得到数值 0 而不是文本表示“ErrorA”。出现此问题的原因是 std::cout 缺乏将枚举转换为字符串的内置支持。
1.使用映射
一种方法是创建一个将每个枚举值与其文本表示关联的映射:
#include <map> #include <string_view> std::ostream& operator<<(std::ostream& out, const Errors value) { static const auto strings = [] { std::map<Errors, std::string_view> result; #define INSERT_ELEMENT(p) result.emplace(p, #p); INSERT_ELEMENT(ErrorA); INSERT_ELEMENT(ErrorB); INSERT_ELEMENT(ErrorC); #undef INSERT_ELEMENT return result; }; return out << strings[value]; }
2。使用结构数组进行线性搜索
另一种选择是使用结构数组,每个结构数组包含一个枚举值及其文本表示形式,然后执行线性搜索:
#include <string_view> std::ostream& operator<<(std::ostream& out, const Errors value) { #define MAPENTRY(p) {p, #p} const struct MapEntry { Errors value; std::string_view str; } entries[] = { MAPENTRY(ErrorA), MAPENTRY(ErrorB), MAPENTRY(ErrorC), {ErrorA, 0} //doesn't matter what is used instead of ErrorA here... }; #undef MAPENTRY const char* s = 0; for (const MapEntry* i = entries; i->str; i++) { if (i->value == value) { s = i->str; break; } } return out << s; }
3。使用 switch/case
最后,我们还可以使用 switch/case 语句:
#include <string> std::ostream& operator<<(std::ostream& out, const Errors value) { return out << [value] { #define PROCESS_VAL(p) case(p): return #p; switch(value) { PROCESS_VAL(ErrorA); PROCESS_VAL(ErrorB); PROCESS_VAL(ErrorC); } #undef PROCESS_VAL }; }
测试解决方案:
为了测试这些解决方案,我们可以使用以下代码创建一个可执行文件:
#include <iostream> int main(int argc, char** argv) { std::cout << ErrorA << std::endl << ErrorB << std::endl << ErrorC << std::endl; return 0; }
运行此可执行文件应输出枚举值的文本表示形式:
ErrorA ErrorB ErrorC
以上是如何在不使用 if/switch 语句的情况下将 C 枚举值打印为文本?的详细内容。更多信息请关注PHP中文网其他相关文章!