gpt4 book ai didi

c++ - C++ 中编译时生成的 block

转载 作者:行者123 更新时间:2023-11-30 02:42:58 25 4
gpt4 key购买 nike

我的服务器中有一个结构,我想用 C++ 中的宏或模板生成它,因为它有很多冗余的东西:

struct MyBlock {
void Merge(const MyBlock& from) {
if (apple.HasData()) {
apple.Merge(from.apple);
}
if (banana.HasData()) {
banana.Merge(from.banana());
}
...
}

void Clear() {
apple.Clear();
banana.Clear();
...
}

void Update(const SimpleBlock& simple_block) {
if (simple_block.apple.Updated()) {
apple.Add(simple_block.apple);
}
if (simple_block.banana.Updated()) {
banana.Add(simple_block.banana);
}
...
}
Fruit apple;
Fruit banana;
Animal dog;
Animal cat;
...
}

struct SimpleBlock {
SimpleFruit apple;
SimpleFruit banana;
SimpleAnimal dog;
SimpleAnimal cat;
...;
}

我想在 apple 和 dog 这两个 block 中定义更多变量。我还想定义更多对这样的 block 。但是涉及到很多琐碎的工作。所以我的问题是我们如何使用宏、模板或其他一些 C++ 功能(包括 C++11)在编译时生成这些 block ?

我不使用集合来存储这些变量的原因是因为 MyBlock 结构将作为参数传递到另一个模板类中,该模板类将在运行时动态分配和释放该 block 。它实际上是一个会定期聚合的线程本地 block 。

最佳答案

预处理器列表迭代足够简单:

#define M_NARGS(...) M_NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define M_NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N

#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B
#define M_ID(...) __VA_ARGS__

#define M_LEFT(L, R) L
#define M_RIGHT(L, R) R

#define M_FOR_EACH(ACTN, ...) M_CONC(M_FOR_EACH_, M_NARGS(__VA_ARGS__)) (ACTN, __VA_ARGS__)

#define M_FOR_EACH_0(ACTN, E) E
#define M_FOR_EACH_1(ACTN, E) ACTN(E)
#define M_FOR_EACH_2(ACTN, E, ...) ACTN(E) M_FOR_EACH_1(ACTN, __VA_ARGS__)
#define M_FOR_EACH_3(ACTN, E, ...) ACTN(E) M_FOR_EACH_2(ACTN, __VA_ARGS__)
#define M_FOR_EACH_4(ACTN, E, ...) ACTN(E) M_FOR_EACH_3(ACTN, __VA_ARGS__)
#define M_FOR_EACH_5(ACTN, E, ...) ACTN(E) M_FOR_EACH_4(ACTN, __VA_ARGS__)
//.. extend this to higher numbers with some copy&paste


#define MYBLOCK(...) struct MyBlock { \
void Merge(const MyBlock& from) { \
M_FOR_EACH(BLOCK_MERGE, __VA_ARGS__) \
} \
void Clear() { \
M_FOR_EACH(BLOCK_CLEAR, __VA_ARGS__) \
} \
void Update(const SimpleBlock& simple_block) { \
M_FOR_EACH(BLOCK_UPDATE, __VA_ARGS__) \
} \
M_FOR_EACH(BLOCK_FIELD, __VA_ARGS__) \
}

#define BLOCK_MERGE(F) if (M_ID(M_RIGHT F).HasData()) { \
M_ID(M_RIGHT F).Merge(from.M_ID(M_RIGHT F)); \
}
#define BLOCK_CLEAR(F) M_ID(M_RIGHT F).Clear;
#define BLOCK_UPDATE(F) if (simple_block.M_ID(M_RIGHT F).Updated()) { \
M_ID(M_RIGHT F).Add(simple_block.M_ID(M_RIGHT F)); \
}
#define BLOCK_FIELD(F) M_ID(M_LEFT F) M_ID(M_RIGHT F);


#define SIMPLEBLOCK(...) struct SimpleBlock { M_FOR_EACH(SIMPLE_DECL, __VA_ARGS__) }
#define SIMPLE_DECL(F) M_CONC(Simple, M_ID(M_LEFT F)) M_ID(M_RIGHT F);

#define FIELDS (Fruit, apple),(Fruit,banana),(Animal,dog),(Animal,cat)

MYBLOCK(FIELDS);
SIMPLEBLOCK(FIELDS);

以现有格式向 FIELDS 添加必要的其他成员变量,它们将被添加到 MYBLOCKSIMPLEBLOCK 发出的结构中. (记得用更多的迭代来扩展 M_FOR_EACH...用几个 ctrl+c,ctrl+v 很容易做到。)

关于c++ - C++ 中编译时生成的 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26568721/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com