enum class Fruit { apple, orange, pear };
enum class Color { red, green, orange };
template <typename T> struct Traits;
//I have to return the appropriate value(string) of color and fruit in their respective structs.
//I could do this by switch case method but I specifically wanted to know, how do I access an enum class through index
template<>
struct Traits<Fruit>{
static string name(int i){
if(i>-1&&i<3){
return Fruit::static_cast<Fruit>(i);
}
else{
return "unknown";
}
}
};
template<>
struct Traits<Color>{
static string name(int i){
if(i>-1&&i<3){
return Color::static_cast<Color>(i);
}
else{
return "unknown";
}
}
};
我想返回相应结构在相应索引处出现的适当字符串。 static_cast无法正常工作,并且编译器给出了无法转换的错误。我不知道是否可以通过索引访问枚举类。
错误:
could not convert ‘(Fruit)i’ from ‘Fruit’ to
‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
return static_cast<Fruit>(i);
答案 0 :(得分:0)
错误提示您不能直接将enum class
转换为字符串。但是您可以使用int
将enum class
转换为static_cast
将int
转换为enum
后,您可以将enum
转换为string
。有很多方法可以做,this so answer对此做了很好的总结
static string name(int i) {
if (i>-1 && i<3) {
Fruit f = static_cast<Fruit>(i);
return name(f);
}
else {
// return default value or throw error
return "";
}
}
static string name(Fruit f) {
//convert f and return string
}
答案 1 :(得分:0)
您可以在与枚举并行的位置添加一系列水果名称,以使其具有名称:
std::string FruitNames[] = { "apple", "orange", "pear" };
现在,您可以直接使用它来获取名称。如果您愿意对x宏进行一点投资,则可以通过一个宏来生成数组和枚举:
#define FRUITS GEN_FRUIT(apple) GEN_FRUIT(orange) GEN_FRUIT(pear)
#define GEN_FRUIT(X) X,
enum class Fruit { FRUITS };
#undef GEN_FRUIT
#define GEN_FRUIT(X) [Fruit::X] = #X,
std::string const FruitNames[] = { FRUITS };
#undef GEN_FRUIT
另一方面,更难以阅读的是,您只有一个位置可以同时维护枚举和数组...
您甚至可以支持显式值:
#define FRUITS GEN_FRUIT_V(apple, 1) GEN_FRUIT(orange) GEN_FRUIT_V(pear, 4)
#define GEN_FRUIT(X) X,
#define GEN_FRUIT_V(X, Y) X = (Y),
enum class Fruit { FRUITS };
#undef GEN_FRUIT
#undef GEN_FRUIT_V
#define GEN_FRUIT(X) GEN_FRUIT_V(X, Fruit::X)
#define GEN_FRUIT_V(X, Y) std::make_pair(static_cast<Fruit>(Y), std::string(#X)),
std::unordered_map<Fruit, std::string> const FruitNames({ FRUITS });
// or (tree) map, if you prefer
//std::map<Fruit, std::string> const FruitNames({ FRUITS });
#undef GEN_FRUIT
#undef GEN_FRUIT_V
在即将发布的C ++ 20(或支持指定初始化程序作为扩展程序的编译器)中,您可以再次使用数组:
#define GEN_FRUIT(X) X,
#define GEN_FRUIT_V(X, Y) X = (Y),
enum class Fruit { FRUITS };
#undef GEN_FRUIT
#undef GEN_FRUIT_V
#define GEN_FRUIT(X) [static_cast<int>(Fruit::X)] = #X,
#define GEN_FRUIT_V(X, Y) GEN_FRUIT(X)
std::string const FruitNames[] = { FRUITS };
#undef GEN_FRUIT
#undef GEN_FRUIT_V
还有未来的音乐...上例中的结果将是一个带有间隙的枚举,并且该阵列在间隙处填充有空字符串。如果差距很大(或存在负的枚举值),那么这种方法也会导致数组较大,因此不再合适,您可能希望再次使用map解决方案...