【问题标题】:c++: get enum value by keyword and the keyword is a variable [duplicate]c ++:通过关键字获取枚举值,关键字是变量[重复]
【发布时间】:2015-12-18 13:44:02
【问题描述】:

在 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 之前有人问过类似的问题,但我不想使用该解决方案,因为我的关键字太多。这样做有什么好主意吗?

【问题讨论】:

  • 只是为了让我自己清楚这个问题:你想要数字中的字符串吗?
  • 您链接到的已接受答案的第二部分仅定义了一次枚举值。因为您无论如何都需要定义适合您的枚举。
  • 不,我想要其他条件和计算中的字符串,我想要字符串中的数字
  • 如果您的编译器支持每个宏 200 多个参数(即您没有使用 Visual C++),请查看此答案:stackoverflow.com/a/31362042/2482998。库版本是here(免责声明:我写的)。

标签: c++ enums


【解决方案1】:

你需要的是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];

【讨论】:

  • 我认为这是唯一正确的答案。 OP 可能不希望这样,但我认为这旁边没有类似的简单方法。我知道 C# 可以做到这一点(所以 Java 很可能也能做到),但 C++ 不能。
  • @YSC 非常感谢您的回答!我想将地图services 放入Defs 类并在sometest 类中执行services[keyword]。我包含了 Defs 类,但是当我这样做时,我收到错误 error C2065: 'services':undeclared identifier。为什么会发生这种情况'
  • @gladys0313 这是另一个问题,您为什么不打开一个新问题并发布您的课程代码?我们很乐意为您提供帮助。
【解决方案2】:

如果您碰巧使用 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 和一个枚举成员函数,可以访问代表Defs::Services 枚举的QMetaEnum

访问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

我希望这会有所帮助。

【讨论】:

    【解决方案3】:

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

    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);
    

    【讨论】:

      猜你喜欢
      • 2013-03-23
      • 2019-08-14
      • 2021-11-15
      • 2010-09-06
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      相关资源
      最近更新 更多