这是我尝试的方法。不幸的是,它依赖于可变参数宏,这是C99/C++1x功能。但在GCC中可以正常工作。
#include <boost/foreach.hpp>
#include <boost/type_traits.hpp>
#include <iostream>
#define SEQ_FOR_EACH(D, ...) \
if(bool c = false) ; else \
for(boost::remove_reference<boost::function_traits<void(D)> \
::arg1_type>::type _t[] = __VA_ARGS__; \
!c; c = true) \
BOOST_FOREACH(D, _t)
int main() {
SEQ_FOR_EACH(std::string &v, { "hello", "doctor" }) {
std::cout << v << std::endl;
}
}
请注意,您也可以使用引用变量进行迭代,以避免无用的复制。以下是使用
boost.preprocessor
和
(a)(b)...
语法的示例,在预处理阶段编译成相同的代码。
#define SEQ_FOR_EACH(D, SEQ) \
if(bool c = false) ; else \
for(boost::remove_reference<boost::function_traits<void(D)> \
::arg1_type>::type _t[] = { BOOST_PP_SEQ_ENUM(SEQ) }; \
!c; c = true) \
BOOST_FOREACH(D, _t)
int main() {
SEQ_FOR_EACH(std::string &v, ("hello")("doctor")) {
std::cout << v << std::endl;
}
}
关键在于组装一个函数类型,该函数类型的参数为枚举变量,并获取该参数的类型。然后使用
boost::remove_reference
来移除任何引用。第一个版本使用了
boost::decay
。但是它也会将数组转换为指针,这有时不是想要的结果。所得到的类型随后用作数组元素类型。
在模板中使用时,如果枚举变量具有依赖类型,则必须使用另一个宏,在
boost::remove_reference
和
boost::function_traits
之前添加
typename
。可以将其命名为
SEQ_FOR_EACH_D
(D == dependent)。