gpt4 book ai didi

c++ - 嵌套宏中带有 BOOST_PP_SEQ_ADD 的 BOOST_PP_SEQ_ELEM?

转载 作者:搜寻专家 更新时间:2023-10-31 02:09:37 24 4
gpt4 key购买 nike

我相信您可以使用 BOOST_PP_SEQ_ELEM(BOOST_PP_ADD(n,1),sequence) ,但我似乎无法确定为什么 EXTRACT下面的宏无法通过“提供的参数太少无法像宏一样运行”进行编译。

#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;
}

这个例子与我想做的相去甚远,但现在我只是想弄清楚如何获得实际的 intzfloaty .

如果重要的话,实际目标是实例化模板。我有一系列模板类,但无法弄清楚如何实例化

//                          vvvvvvvvvvvv
template <class X> void foo(SomeThing<X> varName);

所以这里的标志让我知道如果 SomeThing需求<X>或不。也许有更简单的方法来解决这个问题?我已经在 BOOST_PP_SEQ_FOR_EACH 里面了对于模板中的类,所以我唯一能弄清楚如何做的就是传递这个丑陋的参数序列。 FWIW 我知道 int<X>无效,这只是测试...

最佳答案

诊断提示

一般来说,预处理器宏比“小程序”更容易使用预处理器进行调试。例如,您这里的内容需要完整编译并启动才能看到问题;但是如果你注释掉 #include <iostream>#include <boost/preprocessor/stringize.hpp> , 并将整个主要功能替换为 ALL_ARGS(MY_SEQUENCE) , 然后你可以简单地启动你的预处理器并直接看到它的输出;无需编译/运行。

这不仅速度更快,而且您可以在代币级别上进行游戏以生成可以帮助您的东西,而不必担心生成可以编译的东西。

追踪问题

使用上面的转换,我对 ALL_ARGS 进行了一次扩展(重现问题后)通过更改参数 EXTRACTEXTRACT_ . This iterated just fine .接下来我改变了ALL_ARGS到扩展的输出,打破每个EXTRACT_在不同的行上添加一个人工标签,然后更改 EXTRACT_返回EXTRACT ;例如:

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)

...当EXTRACT以 n=5 运行,这相当于 BOOST_PP_SEQ_ELEM(6, (1)(int)(z)(0)(float)(y)) .这里没有元素偏移量 6,因此宏崩溃了。请注意,BOOST_PP_NOT(BOOST_PP_MOD(5,3))0 , 所以外层 BOOST_PP_IIF不会选择内部那个,但它仍然必须评估它。

替代方法

Perhaps there is an easier way to approach this?

当然。使用不同的数据结构。在这里,您的策略是使用一个大小为 3*n 的序列来表示 n,然后从序列中挑选出每 3 个项目。

通过一些摆弄你当然可以做到这一点,但你需要这样做的全部原因是因为你实际上没有一系列的项目......相反,你有一系列的3 件套。如果将数据结构更改为三元组序列,这将变得容易得多;你只需要一个 IIF , 一个 FOR_EACH , 和几个 worker 宏:

#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#define MY_SEQUENCE ((1,int,z))((0,float,y))
#define APPLY_EXTRACT(r,data,elem) EXTRACT elem
#define EXTRACT(FLAG_,TYPE_,PNAME_) BOOST_PP_IIF(FLAG_, TYPE_, "narp")
#define ALL_ARGS(args) BOOST_PP_SEQ_FOR_EACH(APPLY_EXTRACT, _, MY_SEQUENCE)

ALL_ARGS(MY_SEQUENCE)

See this on stacked-crooked

关于c++ - 嵌套宏中带有 BOOST_PP_SEQ_ADD 的 BOOST_PP_SEQ_ELEM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46407252/

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