C++宏解压缩并加入
C++ macro unpack and join
我正在尝试通过宏定义一个具有变量成员的C++结构,作为内省元数据系统的一部分。鉴于我正在创建一个结构定义,我无法使用编译时模板(对吗?相反,我创建了一个应该接受(类型,名称(元组的可变参数宏,但是我在编写一个宏时遇到了问题,该宏将扩展并用符号连接元组以实现类似
JOIN(.,(a,A)) -> a.A
或JOIN(&,(b,B)) -> b&B
.
我在Visual Studio 2017中工作,我的部分困惑可能是MSVC和GCC中VA_ARGS扩展的不一致: MSVC++ 可变参数宏展开
我的方法是编写一个解压缩宏,它只是从元组中去除括号,以及一个连接宏,该宏将通过所需的字符串连接参数:
#define UNPACK(a, b) a, b
#define JOINAB(a, b, S) a S b
#define JOINTUPLE(S, ab) JOINAB(UNPACK ab, S)
但这不起作用,因为宏似乎没有以正确的顺序进行评估。然后我试图明确扩展论点,例如#define EXPAND(args) args
,但没有运气。
我终于找到了一种解决方法,通过在解包中嵌入参数括号,从而"强制"计算顺序:
#define EXPAND(...) __VA_ARGS__
#define UNPACK(a, b) (a, b
#define JOINAB(a, b, S) a S b
#define JOINTUPLE(S, ab) EXPAND(JOINAB UNPACK ab, S))
这有效,但似乎非常笨拙...
我的问题是
- 有没有适当的方法来实现对未包装结果的评估?
- 为什么我需要扩展?没有它,表达式
JOINTUPLE(:,(a,B))
解析为JOIN (a, B, :)
但为什么不进一步处理以a : B
? - 有没有办法用令牌粘贴运算符来解决它?
S
只存在于 3 个变体中。
在昆汀的评论之后,解决方案是在EXPAND
宏中包含参数括号:
#define EXPAND(...) __VA_ARGS__
#define UNPACK(a, b) a, b
#define JOINAB(a, b, S) a S b
#define JOINTUPLE(S, ab) EXPAND(JOINAB EXPAND((UNPACK ab, S)))
具有可变参数的完整解决方案如下:
#define JOIN1(S, aA) JOINTUPLE(S, aA)
#define JOIN2(S, aA, bB) JOINTUPLE(S, aA), JOINTUPLE(S, bB)
#define JOIN3(S, aA, bB, cC) JOINTUPLE(S, aA), JOINTUPLE(S, bB), JOINTUPLE(S, cC)
#define JOINN(_1, _2, _3, N, ...) JOIN##N
#define JOIN(S,...) _EXPAND(JOINN(__VA_ARGS__,3,2,1)(S,__VA_ARGS__))
这将启用以下语法:
JOIN(:, (a, A)) // Expands to "a : A"
JOIN(., (a, A), (b, B)) // Expands to "a . A, b . B"
为什么需要用这个EXPAND
操作语法的答案,如果它是编译器特定的/可移植的,并且天气是好/坏的做法,将不胜感激。
相关文章:
- 使用C++进行运行长度解压缩
- C++ 如何将数组值解压缩为函数参数
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 在 Qt(C++) 中使用 QProcess 解压缩 - 提取目录问题
- 浏览压缩文件与游览解压缩它们
- 如何在C++向量中解压缩多个值
- 解压缩 C 样式数组以及C++中的参数包
- 如何在 cpp 中解压缩数字,如果它们是使用 struct.pack(fmt, v1, v2, ..) 打包在 pyth
- 如何使用 Poco::ZIP 压缩/解压缩 zip 文件
- 在编译时解压缩数组扩展数据块 (C++11/14)
- 使用 RtMidi 解压缩 Midi 时间码
- 将参数包解压缩到 std::initializer_list?
- 解压缩可变模板参数
- 解压缩附加的压缩字符串
- 使用 AVX2 将 8 位从 32 位值 (__m256i) 解压缩到__m256的最快方法
- C++宏解压缩并加入
- 解压缩串联的 zlib 流而不读取下一个字节
- 解压缩位大小不能被 8 整除的值流
- 为流运算符返回代理类时解压缩参数
- 如何在 Node.js 中解压缩 c# 打包结构