BOOST 预处理器BOOST_PP_LOCAL_ITERATE嵌套循环

BOOST Preprocessor BOOST_PP_LOCAL_ITERATE nested loops

提问人:Sardine 提问时间:9/19/2023 最后编辑:EvgSardine 更新时间:9/19/2023 访问量:42

问:

我有一个模板化的C++函数:

template<int i, int j> void foo();

我想在文件中定义它并显式实例化它。参数和具有相同的允许值范围,从 1 到包含。到目前为止,对于具有单个模板参数的函数,例如.cppijN

template<int i> void foo();

我一直在使用 Boost 预处理器库,如下所示:

#define BOOST_PP_LOCAL_MACRO(n)\
template void foo<n>();
#define BOOST_PP_LOCAL_LIMITS (1,N)
#include BOOST_PP_LOCAL_ITERATE()

此宏扩展为跨度为 1 到 的行,每个行实例化当前值 的函数。NnNn

是否可以使用此库实现嵌套循环?考虑到 C 预处理器的工作原理,这在理论上是否可行?

我在 stackoverflow 上搜索了答案,但没有成功。问题 使用 C 预处理器生成嵌套的 for 循环与我类似,但(与作者不同),如果可能的话,我更喜欢使用 BOOST_PP 库。我试图修改上述宏的尝试毫无头绪,以至于我认为它们并不重要。

C++ 模板 boost-preprocessor explicit-instantiation

评论

1赞 SoronelHaetir 9/19/2023
也许与其试图用BOOST_PP_LOCAL_ITERATE一口气做到这一点,不如用BOOST_PP_LOCAL_ITERATE和BOOST_PP_ITERATE的组合来一分为二。用BOOST_PP_ITERATE做外圈,用BOOST_PP_LOCAL_ITERATE做内圈。
0赞 Sardine 9/19/2023
你是对的,我会将您的评论扩展为答案,因为这已经解决了问题。
1赞 SoronelHaetir 9/19/2023
很高兴给你正确的方向。自从我实际使用 boost 的预处理器迭代以来,已经有足够长的时间了,以至于我完全不愿意尝试将一个快速示例放在一起。

答:

0赞 Sardine 9/19/2023 #1

根据 @SoronelHaetir 的评论,我实施了以下内容。

在文件中:foo_instantiate.ixx

#if !BOOST_PP_IS_ITERATING
   #ifndef FILE_H_
   #define FILE_H_
   #include <boost/preprocessor/iteration/iterate.hpp>
   #define BOOST_PP_ITERATION_PARAMS_1 (3, (1, MAXITER, "foo_instantiate.ixx"))
   #include BOOST_PP_ITERATE()
   #endif
#else
   #include <boost/preprocessor/repetition/repeat_from_to.hpp>
   #define INSTANTIATE(z,n,t) template void foo<1+n,BOOST_PP_ITERATION(),0>();
   BOOST_PP_REPEAT_FROM_TO(0, MAXITER, INSTANTIATE, )
   #undef INSTANTIATE
#endif

这是实现一种文件递归。PP #includes 指定为字符串(此处本身)的文件,其范围为 ((inclusive)。现在,在每个包含中,宏将再次扩展。这允许我们使用标准BOOST_PP迭代宏,这里。当前文件包含迭代是通过 获取的。因此,这实际上可以用作嵌套循环。请注意,不包括最后一个索引。BOOST_PP_ITERATION_PARAMS_1BOOST_PP_REPEAT_FROM_TOBOOST_PP_ITERATION()BOOST_PP_REPEAT_FROM_TO

我这样称呼这个文件是为了将它与头文件区分开来,并避免在CMake中对.cxx文件进行通配的问题。在相应的 cxx 文件(比如 ),我只是 .顺便说一句,CMake 会自动生成一个目标(预处理器输出),这极大地有助于调试这些宏。foo.cxx#include <foo_instantiate.ixx>foo.cxx.i