简体   繁体   English

使用BOOST_PP_SEQ_FOREACH_R递归处理枚举

[英]Using BOOST_PP_SEQ_FOREACH_R to recursively process enums

Related to my question Alternative to expanding templates in a switch statement trying to get Boost.Preprocessor to do a nested interation over a sequence. 与我的问题相关的替代在switch语句中扩展模板的尝试使Boost.Preprocessor在序列上进行嵌套插入。

#include <boost/preprocessor.hpp>
#include <iostream>

#define LASERTYPE_VALUES (EXCIMER)(GAS)(METALVAPOR)(SOLIDSTATE)(DYE)(SEMICONDUCTOR)(FREEELECTRON)(OTHER)

enum LaserType
{
  BOOST_PP_SEQ_ENUM(LASERTYPE_VALUES)
};

#define LT_NESTED(maR, maToplevelType, maNestedType)                    \
  std::cout << "Test nested: first=" << LaserType(maToplevelType) << " second=" << LaserType(maNestedType) << " \n";

#define LT_TOPLEVEL(maR, maUnused, maType)                              \
  std::cout << "Test toplevel: " << LaserType(maType) << " \n";         \
  BOOST_PP_SEQ_FOR_EACH_R(maR, LT_NESTED, maType, LASERTYPE_VALUES);

int main() {
  BOOST_PP_SEQ_FOR_EACH(LT_TOPLEVEL, %%, LASERTYPE_VALUES);
}

This leads to this error: 这导致此错误:

test-pp.cpp: In function ‘int main()’:
test-pp.cpp:15:32: error: ‘LT_NESTED’ was not declared in this scope
   BOOST_PP_SEQ_FOR_EACH_R(maR, LT_NESTED, maType, LASERTYPE_VALUES);
                                ^
/usr/include/boost/preprocessor/seq/for_each.hpp:49:57: note: in expansion of macro ‘LT_TOPLEVEL’
 # define BOOST_PP_SEQ_FOR_EACH_M_I(r, macro, data, seq) macro(r, data, BOOST_PP_SEQ_HEAD(seq))
                                                         ^
test-pp.cpp:4:39: error: ‘EXCIMER’ cannot be used as a function
 #define LASERTYPE_VALUES (EXCIMER)(GAS)(METALVAPOR)(SOLIDSTATE)(DYE)(SEMICONDUCTOR)(FREEELECTRON)(OTHER)
                                       ^
test-pp.cpp:15:51: note: in expansion of macro ‘LASERTYPE_VALUES’
   BOOST_PP_SEQ_FOR_EACH_R(maR, LT_NESTED, maType, LASERTYPE_VALUES);

Reordering the macros doesn't help. 重新排序宏没有帮助。 There's something fundamentally wrong here, and it's likely trivial, but I haven't yet figured out how to do this and haven't seen any decent examples. 这里有一些根本上的错误,这可能是微不足道的,但是我还没有弄清楚如何做到这一点,也没有看到任何不错的例子。 If anyone had any suggestions, I'd be very interested to know what I'm doing wrong here. 如果有人有任何建议,我很想知道我在这里做错了什么。

https://groups.google.com/forum/#!topic/boost-list/jhN4NE9VAtg indicates that I might be running into reentrancy problems. https://groups.google.com/forum/#!topic/boost-list/jhN4NE9VAtg表示我可能会遇到重入问题。 It looks like I might be able to use BOOST_PP_FOR directly for the top level macro perhaps. 看起来我也许可以直接将BOOST_PP_FOR用于顶层宏。 If anyone had an example of that, it would be really useful. 如果有人举个例子,那将非常有用。

I found a workaround in https://groups.google.com/forum/#!topic/boost-devel-archive/Tbcs4nn4sPE which gives this solution: 我在https://groups.google.com/forum/#!topic/boost-devel-archive/Tbcs4nn4sPE中找到了一种解决方法,它提供了以下解决方案:

#include <boost/preprocessor.hpp>
#include <iostream>

#define LASERTYPE_VALUES (EXCIMER)(GAS)(METALVAPOR)(SOLIDSTATE)(DYE)(SEMICONDUCTOR)(FREEELECTRON)(OTHER)

enum LaserType
{
  BOOST_PP_SEQ_ENUM(LASERTYPE_VALUES)
};

#define PP_SEQ_FOR_EACH_R_ID() BOOST_PP_SEQ_FOR_EACH_R 
#define PP_DEFER(x) x BOOST_PP_EMPTY()

#define LT_NESTED(maR, maToplevelType, maNestedType)                    \
  std::cout << "Test nested: first=" << LaserType(maToplevelType) << " second=" << LaserType(maNestedType) << " \n";

#define LT_TOPLEVEL(maR, maUnused, maType)                              \
  std::cout << "Test toplevel: " << LaserType(maType) << " \n";         \
  PP_DEFER(PP_SEQ_FOR_EACH_R_ID)()(maR, LT_NESTED, maType, LASERTYPE_VALUES);

int main() {
  BOOST_PP_EXPAND(BOOST_PP_SEQ_FOR_EACH(LT_TOPLEVEL, %%, LASERTYPE_VALUES));
}

It's a bit esoteric but it compiles and functions as required. 这有点深奥,但可以根据需要进行编译和运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM