我想写一些宏,像这样使用:
MY_ENUM_BEGIN(fun)
ENUM_ENTRY(item1, 1, "item 1")
ENUM_ENTRY(item2, 2, "item 2")
MY_ENUM_END()
它扩展为以下 C++ 代码:
struct fun
{
const static my_item<fun> item1(1, "item 1"); // "fun" is the parameter of the macro "MY_ENUM_BEGIN"
const static my_item<fun> item2(2, "item 2");
std::map<int, my_item<fun>> m_map;
static void register_item()
{
m_map[1] = item1;
m_map[2] = item2;
}
};
如何做到这一点?
我尝试在另一个宏定义中定义一个宏:
#define MY_ENUM_BEGIN(name) \
struct name \
{\
#define ENUM_ENTRY(entry_name, index, text) \
const static my_item<name> entry_name(index, text); \
// ...
但这不起作用(第二个
define
被视为参数,但它不存在)。
尝试通过创建类似枚举的结构、初始化项目和映射来生成带有宏的类。
#include <map>
#include <string>
#include <iostream>
template <typename T>
struct my_item {
int value = 0;
std::string name;
constexpr my_item(int v, const char* n) : value(v), name(n) {}
constexpr my_item() = default;
};
#define MY_ENUM_BEGIN(name) \
struct name { \
using enum_type = name; \
static std::map<int, my_item<enum_type>> m_map; \
static void register_items(); \
#define ENUM_ENTRY(entry_name, index, text) \
const static my_item<enum_type> entry_name;
#define MY_ENUM_END() \
};
#define DEFINE_ENUM_ITEM(enum_name, item_name, index, text) \
const my_item<enum_name::enum_type> enum_name::item_name(index, text);
#define DEFINE_ENUM_MAP(enum_name) \
std::map<int, my_item<enum_name::enum_type>> enum_name::m_map; \
void enum_name::register_items() { \
m_map[item1.value] = item1; \
m_map[item2.value] = item2; \
}
MY_ENUM_BEGIN(fun)
ENUM_ENTRY(item1, 1, "item 1")
ENUM_ENTRY(item2, 2, "item 2")
MY_ENUM_END()
DEFINE_ENUM_ITEM(fun, item1, 1, "item 1")
DEFINE_ENUM_ITEM(fun, item2, 2, "item 2")
DEFINE_ENUM_MAP(fun)
int main() {
fun::register_items();
for (const auto& [key, item] : fun::m_map) {
std::cout << "Key: " << key << ", Name: " << item.name << ", Value: " << item.value << '\n';
}
return 0;
}