C++:将枚举值打印为文本
如果我有一个像这样的enum
:
enum Errors {
ErrorA = 0,
ErrorB,
ErrorC,
};
那么我想将其打印到控制台:
Errors anError = ErrorA;
std::cout << anError; // 0 will be printed
但我想要的是文本“ErrorA”
。我可以不使用 if
/switch
来做到这一点吗?您对此有何解决方案?
If I have an enum
like this:
enum Errors {
ErrorA = 0,
ErrorB,
ErrorC,
};
Then I want to print it out to console:
Errors anError = ErrorA;
std::cout << anError; // 0 will be printed
But what I want is the text "ErrorA"
. Can I do it without using if
/switch
? And what is your solution for this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
您可以使用更简单的预处理器技巧,首先定义命名常量及其值的列表,然后将其用于
enum
定义和switch
。You can use a simpler pre-processor trick to first define the list of named constants and their values, and then use this both for the
enum
definition, and for theswitch
.这是一个好方法,
用字符数组的数组打印它
就像这样
This is a good way,
Print it with an array of character arrays
Like this
这里有一个讨论可能会有所帮助: 有没有一种简单的方法将 C++ 枚举转换为字符串?
更新:
Here#一个 Lua 脚本,它创建一个运算符<<对于它遇到的每个命名枚举。这可能需要一些工作才能使其适用于不太简单的情况 [1]:
给定此输入:
它会产生:
所以这可能是您的开始。
[1] 不同或非命名空间范围中的枚举、带有包含 komma 的初始化表达式的枚举等。
There has been a discussion here which might help: Is there a simple way to convert C++ enum to string?
UPDATE:
Here#s a script for Lua which creates an operator<< for each named enum it encounters. This might need some work to make it work for the less simple cases [1]:
Given this input:
It produces:
So that's probably a start for you.
[1] enums in different or non-namespace scopes, enums with initializer expressions which contain a komma, etc.
每当定义枚举时,我都会使用字符串数组:
Profile.h
Profile.cpp
I use a string array whenever I define an enum:
Profile.h
Profile.cpp
此解决方案不需要您使用任何数据结构或创建不同的文件。
基本上,您在 #define 中定义所有枚举值,然后在运算符 << 中使用它们。与@jxh的答案非常相似。
最终迭代的 ideone 链接:http://ideone.com/hQTKQp
完整代码:
输出:
做一件好事这样,如果您认为需要,您还可以为每个错误指定自己的自定义消息:
输出:
如果您喜欢使错误代码/描述非常具有描述性,则您可能不希望它们出现在生产版本中。关闭它们以便只打印值很容易:
输出:
如果是这种情况,找到错误号 525 将是一个 PITA。我们可以手动指定初始枚举中的数字,如下所示:
输出:
This solution doesn't require you to use any data structures or make a different file.
Basically, you define all your enum values in a #define, then use them in the operator <<. Very similar to @jxh's answer.
ideone link for final iteration: http://ideone.com/hQTKQp
Full code:
Output:
A nice thing about doing it this way is that you can also specify your own custom messages for each error if you think you need them:
Output:
If you like making your error codes/descriptions very descriptive, you might not want them in production builds. Turning them off so only the value is printed is easy:
Output:
If this is the case, finding error number 525 would be a PITA. We can manually specify the numbers in the initial enum like this:
Output:
你可以使用 stl 地图容器......
You could use a stl map container....
static_cast(anError) 应该可以工作。需要将其添加到语言中。
static_cast<std::string>(anError) should work. It needs to be added to the language.
对于这个问题,我做了一个这样的帮助函数:
对于像这样的小集合,线性搜索通常比
std::map
更有效。For this problem, I do a help function like this:
Linear search is usually more efficient than
std::map
for small collections like this.这个怎么样?
等等...我知道这是一个精心设计的示例,但我认为它在适用和需要的地方具有应用程序,并且肯定比为其编写脚本要短。
How about this?
etc... I know this is a highly contrived example but I think it has application where applicable and needed and is certainly shorter than writing a script for it.
使用预处理器:
这种方法的优点是:
- 它仍然很容易理解,但是
- 它允许各种访问(不仅仅是字符串)
如果您愿意放弃第一个,请自己制作一个 FOREACH() 宏,然后
#define ERROR_VALUES() (ErrorA, ErrorB, ErrorC)
和用 FOREACH() 编写您的访问者。然后尝试通过代码审查:)。Use the preprocessor:
The advantage of this approach is that:
- it's still simple to understand, yet
- it allows for various visitations (not just string)
If you're willing to drop the first, craft yourself a FOREACH() macro, then
#define ERROR_VALUES() (ErrorA, ErrorB, ErrorC)
and write your visitors in terms of FOREACH(). Then try to pass a code review :).使用作用域 C++ 枚举的方法:
An approach using scoped c++ enums:
使用映射:
使用结构数组进行线性搜索:
使用 switch/case:
测试解决方案:
Using map:
Using array of structures with linear search:
Using switch/case:
Test the solutions:
使用具有匹配值的字符串数组:
还要考虑是否将数组设为静态、内联或外部。选择取决于它所在的位置以及您使用的 C++ 标准。
编辑:上面的解决方案适用于枚举是连续的,即从 0 开始并且没有分配值。它将与问题中的枚举完美配合。
为了进一步证明 enum 不从 0 开始的情况,请使用:
Use an array of strings with matching values:
Also consider whether to make the array
static
,inline
, orextern
. The choice depends on where it's located and which C++ standard you're using.EDIT: The solution above is applicable when the enum is contiguous, i.e. starts from 0 and there are no assigned values. It will work perfectly with the enum in the question.
To further proof it for the case that enum doesn't start from 0, use:
这是一个基于 Boost.Preprocessor 的示例:
Here is an example based on Boost.Preprocessor: