c ++:按关键字获取枚举值,关键字是变量

时间:2015-12-18 13:44:03

标签: c++ enums

在c ++类Defs中,我有一个像enum services {1st_drink = 101, 2nd_drink = 105, seafood_outside = 200,......}这样的公共枚举。我有大约200个关键字,每个关键字都有一个值。现在在另一个类sometest中,我需要获取特定的关键字值。关键字就像我的代码中的变量一样,我只能在经过一些处理后知道关键字。所以我想做的就是:

.......
std::string keyword = string1 + "_" + string2;
unsigned int a = Defs::keyword;
.......

但是现在当我尝试这样做时,我收到错误"error C2039: 'keyword': is not a member of 'Defs'""error C2440: '=': cannot convert from 'std::string' to 'const unsigned int '"

现在我尝试解决问题。我注意到有人在Get enum value by name之前问了一个类似的问题但我不想使用那个解决方案,因为我有太多的关键字。这样做有什么好主意吗?

3 个答案:

答案 0 :(得分:4)

您需要的是std::map<std::string, unsigned int>

#include <map>
#include <string>

const std::map<std::string, unsigned int> services = {
    { "1st_drink", 101 },
    { "2nd_drink", 200 },
    // ...
};

const std::string keyword = string1 + "_" + string2;
const unsigned int a = services[keyword];

答案 1 :(得分:1)

如果您正在使用Qt应用程序框架,您可以利用Qt的元对象编译器,该编译器存储有关在运行时使用的类的信息。 MOC可以识别枚举。

class Defs: public QObject {
    Q_OBJECT
    enum  Services { firstDrink = 1, secondDrink = 2, ... };
    Q_ENUMS(Services)
};

当moc在上面运行并看到Q_OBJECT时,它会添加staticMetaObject类型QMetaObject成员。此QMetaObject实例具有indexOfEnumerator和枚举器成员函数,可以访问代表QMetaEnum枚举的Defs::Services

访问QMetaEnum成员的代码如下所示:

const QMetaObject &mo = Defuns::staticMetaObject;
int index = mo.indexOfEnumerator("Services");
QMetaEnum metaEnum = mo.enumerator(index);

然后我们可以使用QMetaEnum对象,如下所示:

// first, let's convert from an enum value to a string
Services s = Defs::firstDrink;
QByteArray str = metaEnum.valueToKey(s);
// str now contains "firstDrink"

// second, let's convert from a string to an enum value:
int value = metaEnum.keyToValue("firstDrink");
// value now contains the integer 1

我希望这会有所帮助。

答案 2 :(得分:0)

作为可重用的通用解决方案,您可以在声明枚举时创建这样的枚举解析器模板:

template <typename T>
class EnumParser
{
    map <string, T> enumMap;
    T defaultValue;
public:
    EnumParser(){};

    T Parse(const string &value)
    { 
        map <string, T>::const_iterator iValue = enumMap.find(value);
        if (iValue  == enumMap.end())
            return defaultValue;
        return iValue->second;
    }       
};

您可以像这样使用实例化:

enum class Services
{
    DeFault,
    First_drink = 101,
    Second_drink = 105,
    seafood_outside = 200,
};

EnumParser<Services>::EnumParser() : defaultValue(Services::DeFault)
{
    enumMap["DeFault"] = Services::DeFault;
    enumMap["First_drink"] = Services::First_drink;
    enumMap["Second_drink"] = Services::Second_drink;
    enumMap["seafood_outside"] = Services::seafood_outside;
}

然后像这样使用它:

int value= (int)EnumParser<Services>().Parse(keyword);