用于生成链表的宏
A Macro for Building a Linked List
我正在以编程方式生成C++代码。我经常必须输出以下形式的链表,
PTR(new List(a,PTR(new List(NULL,NULL))))
PTR(new List(a, PTR(new List(b,PTR(new List(NULL,NULL))))))
随着列表大小的增长,生成的代码变得越来越丑陋,我想知道是否可以定义表单的可变参数宏,
LIST(a)
LIST(a,b)
这将扩展到第一种形式的代码。
以下是使用 Boost.Preprocessor 的一种方法,它不依赖于 Boost 的任何其他部分:
#include <boost/preprocessor.hpp>
#define FOR_EACH_OP(r, data, elem) PTR(new List(elem,
#define DOUBLE_RPAREN(...) ))
#define LIST(...) LIST_I(BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
#define LIST_I(seq)
BOOST_PP_SEQ_FOR_EACH(FOR_EACH_OP, /*empty*/, seq)
PTR(new List(NULL,NULL))
BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), DOUBLE_RPAREN, /*empty*/)
LIST(a) // PTR(new List(a, PTR(new List(NULL,NULL)) ))
LIST(a,b) // PTR(new List(a, PTR(new List(b, PTR(new List(NULL,NULL)) )) ))
LIST
只是将参数转换为"PP 序列",这提供了一个方便FOR_EACH
。对于每个参数,将构建左侧部分。然后添加NULL
部分。最后,根据给出的参数数添加匹配的右括号。
免责声明:LIST()
将无法按预期工作,因为这是一个带有一个(空(参数的调用。
如果你真的对Boost过敏,你可以制作这些的简化版本。例如,一种支持最多四个参数的方法:
#define CAT(_0, _1) CAT_I(_0, _1)
#define CAT_I(_0, _1) _0##_1
#define ARG5(_0, _1, _2, _3, _4, ...) _4
#define NARGS(...) ARG5(__VA_ARGS__, 4, 3, 2, 1,)
#define OVERLOAD(prefix, ...) CAT(prefix, NARGS(__VA_ARGS__))
#define ELEM(i, ...) CAT(ELEM_, i)(__VA_ARGS__,)
#define ELEM_0(_0, ...) _0
#define ELEM_1(_0, _1, ...) _1
#define ELEM_2(_0, _1, _2, ...) _2
#define ELEM_3(_0, _1, _2, _3, ...) _3
#define FOR_EACH(macro, ...) OVERLOAD(FOR_EACH_, __VA_ARGS__)(macro, __VA_ARGS__)
#define FOR_EACH_1(macro, ...) macro(ELEM(0, __VA_ARGS__))
#define FOR_EACH_2(macro, ...) FOR_EACH_1(macro, __VA_ARGS__) macro(ELEM(1, __VA_ARGS__))
#define FOR_EACH_3(macro, ...) FOR_EACH_2(macro, __VA_ARGS__) macro(ELEM(2, __VA_ARGS__))
#define FOR_EACH_4(macro, ...) FOR_EACH_3(macro, __VA_ARGS__) macro(ELEM(3, __VA_ARGS__))
#define REPEAT(n, macro) CAT(REPEAT_, n)(macro)
#define REPEAT_1(macro) macro()
#define REPEAT_2(macro) REPEAT_1(macro) macro()
#define REPEAT_3(macro) REPEAT_2(macro) macro()
#define REPEAT_4(macro) REPEAT_3(macro) macro()
#define FOR_EACH_MACRO(elem) PTR(new List(elem,
#define DOUBLE_RPAREN() ))
#define LIST(...) LIST_I(NARGS(__VA_ARGS__), __VA_ARGS__)
#define LIST_I(n, ...)
FOR_EACH(FOR_EACH_MACRO, __VA_ARGS__)
PTR(new List(NULL,NULL))
REPEAT(n, DOUBLE_RPAREN)
LIST(a) // PTR(new List(a, PTR(new List(NULL,NULL)) ))
LIST(a,b) // PTR(new List(a, PTR(new List(b, PTR(new List(NULL,NULL)) )) ))
相关文章:
- 反向给定链表中的K节点
- 如果没有malloc,链表实现将失败
- 重载运算符 += 用于 C++ 中的链表
- 这个用于清空链表的代码可以吗?
- 取消排队不适用于从双链表继承的队列类
- 为什么T是未定义的?我正在尝试实现一个用于双链表的节点类,它不喜欢我使用友元运算符后的T
- 用于在链表中查找节点的算法
- 递归解决方案,用于显示线性链表数组
- 我应该将 malloc() 用于链表吗?
- 基于范围的 for 循环,用于包含C++中的指针的自定义链表,仅返回对象
- 如何在用于删除节点的函数中检查我的链表是否C++为空
- 单个或单个头用于链表的动态数组
- 链表与动态数组用于使用向量类实现堆栈
- 为什么结构 *节点接下来适用于C++中的链表
- 用于对链表进行排序的继承,而不会造成混乱
- 用于生成链表的宏
- 重载用于添加两个双链表的运算符
- 为什么此代码不适用于删除链表中的节点?
- c++中用于字符串优先级队列的未排序双链表
- malloc和heap:用于存储大小和链表信息的额外内存