It looks like like you are trying to define an enum Error
that also has the strings as members. I will give you my own solution to this problem. (I'm not addressing the question but I believe that my answer is relevant for what I understand that OP is trying to do.)
And I just realized that OP is targeting C, not C++, so not sure if this can be done...
In MyEnum.hpp
#define MYENUM(X,...) \
struct X { \
enum Enum {__VA_ARGS__}; \
static const std::vector<std::string> names; \
static X::Enum which(const std::string& s) { \
return static_cast<X::Enum>(findEnum(s,names)); \
} \
static std::string str(X::Enum i) { \
return names[i];} \
}
Here findEnum()
is just a linear search over the vector that returns the position index (additionally, in my implementation if it doesn't find it it throws an exception with all the possible correct inputs, I also do case insensitive comparison). Note that an ordered map instead of a vector would be more efficient (O(log(n)) instead of O(n)), but I didn't cared much because the size of those things is very small in my case.
Below the previous macro, declare your enum as
MYENUM(Error,Connect,Timeout); // I put the semicolon here not in the macro
And in MyEnum.cpp
, add
#include <boost/assign/list_of.hpp>
const std::vector<std::string> Error::names = boost::assign::list_of
("Connect")("Timeout");
(I think that it should be possible to use initialization lists with a modern compiler). The important thing here is to make sure that the order is the same, otherwise it will not work.
Then, you can do stuff like this:
Error::Enum err1 = Error::Connect;
Error::Enum err2 = Error::which("Timeout");
std::cout << "Got " << Error::str(err1) << " error. Not good.\n";