如何同时迭代两个 Boost 预处理器序列?
How to iterate over two Boost Preprocessor sequences at the same time?
我想知道是否可以通过 Boost 预处理器序列完成以下操作。 (大多数 SO 问题以及 Boost 预处理器示例只讨论 1 个序列)
#define seq1 (a)(b)(c)
#define seq2 (1)(2)(3)
// Now iterate over both of them at the same time
这是我的动力。我必须为很多类型定义一些函数,例如
void add(int val) { obj.AddInt(val); }
void add(double val) { obj.AddDouble(val); }
我正在考虑定义两个序列,例如
#define types (int)(double)...
#define funcs (AddInt)(AddDouble)...
然后为函数add写一个宏,迭代两个序列。
您可以使用 BOOST_PP_SEQ_FOR_EACH_I
and BOOST_PP_SEQ_ELEM
进行如下操作:
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#define types (int)(double)
#define funcs (AddInt)(AddDouble)
#define MACRO(_,funcs,i,type) \
void add(type val) { obj.BOOST_PP_SEQ_ELEM(i, funcs)(val); }
BOOST_PP_SEQ_FOR_EACH_I(MACRO, funcs, types)
BOOST_PP_SEQ_FOR_EACH_I
宏迭代序列 types
,对每个元素应用 MACRO
。 BOOST_PP_SEQ_FOR_EACH_I
的第二个参数作为第二个参数传递给 MACRO
的每个调用,并且 i
表示正在迭代的当前元素的 zero-based 索引。因此,当展开 MACRO
时,type
是 types
的第 i
个元素,而 BOOST_PP_SEQ_ELEM(i, funcs)
是 i
的第 i
个元素funcs
.
对于更通用的解决方案,您可以执行以下操作:
#define ITERATE_OVER_TWO_SEQ_(_,data,i,e2) \
BOOST_PP_SEQ_ELEM(0,data)(BOOST_PP_SEQ_ELEM(i, BOOST_PP_SEQ_ELEM(1,data)), e2)
#define ITERATE_OVER_TWO_SEQ(macro, s1, s2) \
BOOST_PP_SEQ_FOR_EACH_I(ITERATE_OVER_TWO_SEQ_, (macro)(s1), s2)
并按如下方式使用它:
#define MACRO(type,func) void add(type val) { obj.func(val); }
ITERATE_OVER_TWO_SEQ(MACRO, types, funcs)
一种更通用的方法是使用 、BOOST_PP_SEQ_FOR_EACH
和 BOOST_PP_SEQ_ELEM
中的 SEQ_ZIP
。例如:
#include <boost/preprocessor/seq/for_each.hpp>
#define MACRO(_,d,seq) \
void add(BOOST_PP_SEQ_ELEM(0,seq) val) \
{ obj.BOOST_PP_SEQ_ELEM(1, seq)(val); }
BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ_ZIP((types)(funcs))
我想知道是否可以通过 Boost 预处理器序列完成以下操作。 (大多数 SO 问题以及 Boost 预处理器示例只讨论 1 个序列)
#define seq1 (a)(b)(c)
#define seq2 (1)(2)(3)
// Now iterate over both of them at the same time
这是我的动力。我必须为很多类型定义一些函数,例如
void add(int val) { obj.AddInt(val); }
void add(double val) { obj.AddDouble(val); }
我正在考虑定义两个序列,例如
#define types (int)(double)...
#define funcs (AddInt)(AddDouble)...
然后为函数add写一个宏,迭代两个序列。
您可以使用 BOOST_PP_SEQ_FOR_EACH_I
and BOOST_PP_SEQ_ELEM
进行如下操作:
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#define types (int)(double)
#define funcs (AddInt)(AddDouble)
#define MACRO(_,funcs,i,type) \
void add(type val) { obj.BOOST_PP_SEQ_ELEM(i, funcs)(val); }
BOOST_PP_SEQ_FOR_EACH_I(MACRO, funcs, types)
BOOST_PP_SEQ_FOR_EACH_I
宏迭代序列 types
,对每个元素应用 MACRO
。 BOOST_PP_SEQ_FOR_EACH_I
的第二个参数作为第二个参数传递给 MACRO
的每个调用,并且 i
表示正在迭代的当前元素的 zero-based 索引。因此,当展开 MACRO
时,type
是 types
的第 i
个元素,而 BOOST_PP_SEQ_ELEM(i, funcs)
是 i
的第 i
个元素funcs
.
对于更通用的解决方案,您可以执行以下操作:
#define ITERATE_OVER_TWO_SEQ_(_,data,i,e2) \
BOOST_PP_SEQ_ELEM(0,data)(BOOST_PP_SEQ_ELEM(i, BOOST_PP_SEQ_ELEM(1,data)), e2)
#define ITERATE_OVER_TWO_SEQ(macro, s1, s2) \
BOOST_PP_SEQ_FOR_EACH_I(ITERATE_OVER_TWO_SEQ_, (macro)(s1), s2)
并按如下方式使用它:
#define MACRO(type,func) void add(type val) { obj.func(val); }
ITERATE_OVER_TWO_SEQ(MACRO, types, funcs)
一种更通用的方法是使用 BOOST_PP_SEQ_FOR_EACH
和 BOOST_PP_SEQ_ELEM
中的 SEQ_ZIP
。例如:
#include <boost/preprocessor/seq/for_each.hpp>
#define MACRO(_,d,seq) \
void add(BOOST_PP_SEQ_ELEM(0,seq) val) \
{ obj.BOOST_PP_SEQ_ELEM(1, seq)(val); }
BOOST_PP_SEQ_FOR_EACH(MACRO, _, SEQ_ZIP((types)(funcs))