所以,我为我经常使用的几个枚举实现了一个enumToString
函数(经常在SO中询问:Is there a simple way to convert C++ enum to string?,Easy way to use variables of enum types as string in C?,...)。
这使得错误消息WAY更容易调试,但我必须维护函数来添加有时没有字符串描述的值。
我的代码如下所示:
typedef std::map<my_enum_e, const char *> enum_map_t;
static bool s_enum_map_initialized = false;
static enum_map_t s_enum_strings;
static void s_init_maps()
{
#define ADD_ENUM( X ) s_enum_strings[X] = #X;
if( s_enum_strings.size() == 0)
{
ADD_CLASS( MY_ENUM_1 );
ADD_CLASS( MY_ENUM_2 );
/* ... all enums */
}
s_enum_map_initialized = true;
}
const char *Tools::enumCString( my_enum_e e )
{
if( ! s_enum_map_initialized )
{
s_init_maps();
}
// todo: use the iterator instead of searching twice
if( s_enum_strings.find(e) != s_enum_strings.end() )
{
return s_class_strings[e];
}
return "(unknown enum_e)";
}
现在,我想要的是,当我不在地图中找到枚举时,返回"(unknown enum %d)", e
。这将给我我错过的枚举的价值。
这样,即使我没有将它添加到地图中,我仍然有它的价值,我可以调试我的程序。
我找不到简单的方法:在返回后立即销毁堆栈上的字符串流,静态字符串流不是线程安全的,...
编辑:当然,使用std::string
作为返回类型可以让我对其进行格式化,但我在代码中经常调用这些函数,我想通过{{1指针更快,因为我不必每次都将std :: string推入堆栈。
任何解决方案?
答案 0 :(得分:4)
返回std::string
而不是char*
。
这样您就可以使用std::stringstream
生成邮件了。然后,调用站点必须使用.c_str( )
上的std::string
成员函数来获取C样式指针(如果需要)。
答案 1 :(得分:3)
就个人而言,我使用BOOST:)
使用示例:
SANDBOX_DEFINE_ENUM(MyEnum, (Foo)(Bar)(Team))
将屈服:
struct MyEnum {
enum Type {
Foo,
Bar,
Team
};
static Type const First = Foo;
static Type const Last = Team;
};
inline char const* toString(MyEnum::Type value) {
switch(value) {
case MyEnum::Foo: return "Foo";
case MyEnum::Bar: return "Bar";
case MyEnum::Team: return "Team";
}
return 0;
}
代码:
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/reverse.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#define SANDBOX_DEFINE_ENUM(Name_, Values_) \
SANDBOX_DEFINE_ENUM_TYPE(Name_, Values_) \
SANDBOX_DEFINE_ENUM_STRING(Name_, Values_)
#define SANDBOX_DEFINE_ENUM_TYPE(Name_, Values_) \
struct Name_ { \
enum Type { \
BOOST_PP_SEQ_ENUM(Values_) \
}; \
static Type const First = BOOST_PP_SEQ_HEAD(Values_); \
static Type const Last = BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(Values_)); \
};
#define SANDBOX_DEFINE_ENUM_STRING(Name_, Values_) \
inline char const* toString(Name_::Type value) { \
switch(value) { \
BOOST_PP_SEQ_FOR_EACH(SANDBOX_DEFINE_ENUM_TO_STRING_C, Name_, Values_) \
} \
return 0; \
}
#define SANDBOX_DEFINE_ENUM_TO_STRING_C(r, Name_, Elem_) \
case Name_::Elem_: return BOOST_PP_STRINGIZE(Elem_);
显然,它只适用于“常规”枚举,而不适用于定制的枚举。但是因为它在代码中的一个地方定义了......没有维护惩罚:)
答案 2 :(得分:0)
答案 3 :(得分:0)
在这种情况下,我不会返回值。我会抛出异常并让您的消息包含无效枚举器的值。对我来说,无效的枚举器值似乎是一个错误。
如果你不想这样做,那么我同意其他人你应该返回一个std :: string。