c++ - 使用 C++11 可变参数模板初始化 Enum To String Map

标签 c++ qt c++11

我认为可以使用 C++11 中引入的 Variadic 模板参数来初始化一个映射,该映射的键是整数,值是给定参数的字符串表示法。

如果可能的话,我可以简单地创建一个从枚举名称到它的字符串表示的映射,如下所示:

auto map = EnumStringMap<EnumType::Type1, EnumType::Type2>();

我可以通过这个模板用 enum int 表示初始化一个列表

template<typename... Ts> auto enumList(Ts... args){
    QList<int> res = {args...};
    return res;
}

auto enums =  enumList<int, int>(Enums::Enum1, Enums::Enum2);

我认为应该可以使用 STRINGFY C 宏来获取表达式的字符串表示

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

但我无法弄清楚如何将类型名称或类型值转换为其字符串表示形式,所以这可能吗? 我的目标是生成一个映射,其中包含编译时枚举的字符串表示形式。

qt 使用的 MOC 等方法不适合我,因为我应该将枚举包含在 QObject 中,它很重且不可复制。

最佳答案

在任何 C++ 编译之前,宏由预处理器处理。因此,您不能在函数内使用宏来检索枚举值的 C++ 名称。

大多数解决方案都基于在定义枚举时使用的宏。 Internet 上有许多可用的实现,它们通常会执行以下操作:

#define MY_ENUM(a, b, c) enum a {b , c} \
Map<a, string> mymap = {{b, STRINGIFY(b)}, {b, STRINGIFY(b)}};

MY_ENUM(Color, Red, Blue)
MY_ENUM(Align, Left, Right)

另一种方法是使用元编译器,它将处理 C++ 代码以生成更多代码。这就是 Qt 用它的 moc 做的,因为你用 Qt 标记了你的问题,这可能是最适合你的方式..

class FooBar : public QObject {
  Q_OBJECT
public:
  enum Action { Open, Save, New, Copy, Cut, Paste, Undo, Redo, Delete };
  Q_ENUM(Action) // Not Q_ENUMS !!!

  static QString convert(Action a) {
    auto metaEnum = QMetaEnum::fromType<Action>();
    return metaEnum.valueToKey(a);
  }
};

这有一些限制,例如必须在 QObject(或 Q_GADGET)中定义枚举。您可以在 Qt documentation 中找到更多信息.关于它是如何完成的,你可以看到 Woboq article .

关于c++ - 使用 C++11 可变参数模板初始化 Enum To String Map,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47280968/

相关文章:

c++ - pthread_attr_setstacksize 和 pthread_exit

qt - QSslSocket waitForReadyRead 似乎没有工作

python - WAF 自动化 qt 配置

c++ - 多精度初等函数实现

c++ - 创建可点击的 "buttons"C++

c++ - 从文本文件中读取整数

c++ - QWebView::settings()->setUserStyleSheetUrl() 从 QtWebKit 到 QtWebEngine?

c++ - 为什么编译器会尝试实例化一个我实际上并没有在任何地方实例化的模板?

c++ - 是否可以在编译时检查 const 值是否已知?

c++ - 使用 std::function 作为 lambda 参数调用函数