英文:
I want to use macros or template metaprogramming to generate some code for me
问题
Sure, here's the translated code part:
我需要定义一个枚举,类似于
enum class MyEnum { MyEnum1 = 0x0001, MyEnum2 = 0x0002, MyEnum3 = 0x0004, MyEnum4 = 0x0008, MyEnum5 = 0x0010 };
所以基本上这些枚举值是1左移枚举索引,我希望在将来某人添加新的枚举值时避免任何拼写错误,我可以简单地为命名枚举定义一个字符串数组并生成相应的函数,根据枚举的索引返回值。
这可以分解成以下内容。假设我有一个数组
constexpr std::array<const char*, 3> arr = {"Foo", "Bar", "Baz"};
//现在在编译时我想生成函数
constexpr int getFoo() { return 0; }
constexpr int getBar() { return 1; }
constexpr int getBaz() { return 2; }
基本上,我想遍历数组并生成数组中值的getter函数,然后返回数组中的索引。
不确定是否可能,但我模糊记得可以使用宏中的 ## 生成这样的代码。
<details>
<summary>英文:</summary>
I need to define an enum like
enum class MyEnum { MyEnum1 = 0x0001, MyEnum2 = 0x0002, MyEnum3 = 0x0004, MyEnum4 = 0x0008, MyEnum5 = 0x0010 };
So basically these enum values are 1 shifted by the index of enum I want to avoid any typos in case in future some adds a new enum value and I can simply define an array of string for the named enums and generate functions for it and return value based on the index of enum.
this can be broken down to something like this . Say I have an array
constexpr std::array<const char*, 3> arr = {"Foo", "Bar", "Baz"};
//Now at compile time i want to generate functions
constexpr int getFoo() { return 0; }
constexpr int getBar() { return 1; }
constexpr int getBaz() { return 2; }
Basically i want to iterate over array and generate getter functions over the values in array and return the index in array.
Not sure even if its possible but vaguely remember such code being generated using ## in macros
</details>
# 答案1
**得分**: 3
> 我需要定义一个枚举,类似这样的枚举类:enum class MyEnum { MyEnum1 = 0x0001, MyEnum2 = 0x0002, MyEnum3 = 0x0004, MyEnum4 = 0x0008, MyEnum5 = 0x0010 };
请查看 [`macro_sequence_for`](https://github.com/HolyBlackCat/macro_sequence_for)。这几乎与自述文件中的第一个示例几乎完全相符。
<kbd>[在 gcc.godbolt.org 上运行][1]</kbd>
```cpp
#include "macro_sequence_for.h"
#define MAKE_FLAGS(name, seq) enum name {SF_FOR_EACH(BODY, STEP, FINAL, 0, seq)};
#define BODY(n, d, x) x = 1 << (d),
#define STEP(n, d, x) d+1
#define FINAL(n, d) _mask = (1 << (d)) - 1
MAKE_FLAGS(E, (a)(b)(c))
这会扩展为:
enum E
{
a = 1 << (0), // 0b0001
b = 1 << (0+1), // 0b0010
c = 1 << (0+1+1), // 0b0100
_mask = (1 << (0+1+1+1)) - 1 // 0b0111
};
如果您不需要组合的掩码,可以删除 #define FINAL
并在其位置传递 SF_NULL
。
完整披露 - 我是该库的作者。
英文:
> I need to define an enum like enum class MyEnum { MyEnum1 = 0x0001, MyEnum2 = 0x0002, MyEnum3 = 0x0004, MyEnum4 = 0x0008, MyEnum5 = 0x0010 };
Take a look at macro_sequence_for
. This almost exactly matches the very first example in the readme.
<kbd>run on gcc.godbolt.org</kbd>
#include "macro_sequence_for.h"
#define MAKE_FLAGS(name, seq) enum name {SF_FOR_EACH(BODY, STEP, FINAL, 0, seq)};
#define BODY(n, d, x) x = 1 << (d),
#define STEP(n, d, x) d+1
#define FINAL(n, d) _mask = (1 << (d)) - 1
MAKE_FLAGS(E, (a)(b)(c))
This expands to:
enum E
{
a = 1 << (0), // 0b0001
b = 1 << (0+1), // 0b0010
c = 1 << (0+1+1), // 0b0100
_mask = (1 << (0+1+1+1)) - 1 // 0b0111
};
If you don't need the combined mask, remove #define FINAL
and pass SF_NULL
in its place.
Full disclosure - I'm the library author.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论