我确信您可以使用BOOST_PP_SEQ_ELEM(BOOST_PP_ADD(n,1),sequence)
,但我似乎无法确定以下EXTRACT
宏无法使用&#34进行编译的原因提供的参数像macro"。
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/arithmetic/mod.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <iostream>
// attempt 2.7 beta
#define EXTRACT(z, n, args) \
BOOST_PP_IIF(\
/* on every third index */ \
BOOST_PP_NOT(BOOST_PP_MOD(n,3)),\
/* check the flag */ \
BOOST_PP_IIF(BOOST_PP_SEQ_ELEM(n,args),\
/*BOOST_PP_SEQ_ELEM(n,args),*/ \
BOOST_PP_SEQ_ELEM(BOOST_PP_ADD(n,1),args),\
"narp"\
),\
)
// absurd wrapper for extract
#define ALL_ARGS(args) BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(args),EXTRACT,args)
// every third element is a "flag"
// v v
#define MY_SEQUENCE (1)(int)(z)(0)(float)(y)
int main(int argc, const char **argv) {
std::cout <<
BOOST_PP_STRINGIZE(ALL_ARGS(MY_SEQUENCE))
<< std::endl;
}
这个例子远非我想要做的事情,但是现在我只想弄清楚如何获得实际的int
和z
或{{1} }和float
。
如果重要,实际目标是实例化模板。我有一系列模板类,但我无法弄清楚如何实例化
y
所以这里的标志让我知道// vvvvvvvvvvvv
template <class X> void foo(SomeThing<X> varName);
是否需要SomeThing
。也许有一种更简单的方法来解决这个问题?我已经在模板中的类<X>
内了,所以我唯一能弄清楚如何做的就是传递这个丑陋的参数序列。 FWIW我知道BOOST_PP_SEQ_FOR_EACH
不是有效的,这只是测试......
答案 0 :(得分:2)
一般情况下,预处理器宏使用预处理器比使用预处理器更容易调试&#34;微小程序&#34;。例如,您在此处需要完整的编译和启动以查看问题;但是如果你注释掉#include <iostream>
和#include <boost/preprocessor/stringize.hpp>
,并用ALL_ARGS(MY_SEQUENCE)
替换整个主函数,那么你可以直接启动预处理器并查看其输出;无需编译/运行。
这不仅速度更快,而且您可以在令牌级别上进行游戏,以制作可以帮助您的内容,而不必担心会产生可编译的内容。
使用上面的转换,我通过将参数ALL_ARGS
更改为EXTRACT
,对EXTRACT_
进行了单次扩展(在重现问题之后)。 This iterated just fine。接下来,我将ALL_ARGS
更改为扩展的输出,在单独的行中分解每个EXTRACT_
并添加人工标签,然后将EXTRACT_
更改回EXTRACT
; e.g:
0_ EXTRACT(2, 0, (1)(int)(z)(0)(float)(y))
1_ EXTRACT(2, 1, (1)(int)(z)(0)(float)(y))
...
再次通过预处理器运行,显示所有扩展都很好,except for the sixth one:
5_ EXTRACT(2, 5, (1)(int)(z)(0)(float)(y))
考虑到这一点很容易发现。问题确实存在于这一部分:
BOOST_PP_SEQ_ELEM(BOOST_PP_ADD(n,1),args)
...当{= 1}}以n = 5运行时,这相当于EXTRACT
。这里没有元素偏移6,因此宏崩溃。请注意,BOOST_PP_SEQ_ELEM(6, (1)(int)(z)(0)(float)(y))
为BOOST_PP_NOT(BOOST_PP_MOD(5,3))
,因此外部0
不会选择内部,但它仍然必须评估 it。
也许有更简单的方法来解决这个问题?
绝对。使用不同的数据结构。在这里,你的策略是对一些n使用大小为3 * n的序列,然后在序列中挑选出每3个项目。
通过一些摆弄你肯定可以做到这一点,但你需要的全部原因是因为你没有真正拥有一系列项目 ......而是你有一系列的 3件套。如果将数据结构更改为3元组序列,则更多更容易;您只需要一个BOOST_PP_IIF
,一个IIF
和一些工作宏:
FOR_EACH