【发布时间】:2014-07-11 01:36:05
【问题描述】:
我想要一个宏,它接受任意偶数个参数,将每一对拼接在一起,在末尾添加一些名称,比如说Type,然后将它们作为模板参数传递给某种类型,我们称之为CompileTimeList .所以我会给它这样的东西:
MACRO( \
First,Set, \
Second,Type, \
Third,Thing)
它会扩展为:
CompileTimeList<
FirstSetType,
SecondTypeType,
ThirdThingType>
天真的解决方案是可变参数递归模板,这是不允许的:
我可以使用这种方法手动组合一个宏:
Macro recursive expansion to a sequence
但它仅限于我定义的许多参数。我希望能够扩展任意长度的参数。这在 C++11 中可行吗?我也有可用的 Boost 1.55,其他问题中没有提到。
为了尝试实现 chris 的回答,我编写了以下程序:
1 #include <boost/preprocessor.hpp>
2
3 #include <vector>
4 #include <algorithm>
5
6 #define MACRO(...) \
7 std::find( \
8 BOOST_PP_ENUM( \
9 BOOST_PP_DIV(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 2), \
10 ENUM_MACRO, \
11 BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__) \
12 ) \
13 )
14
15 #define ENUM_MACRO(z, n, data) \
16 BOOST_PP_CAT( \
17 BOOST_PP_CAT( \
18 BOOST_PP_TUPLE_ELEM(BOOST_PP_MUL(n, 2), data), \
19 BOOST_PP_TUPLE_ELEM(BOOST_PP_INC(BOOST_PP_MUL(n, 2)), data) \
20 ), \
21 Type \
22 )
23
24
25 typedef int FirstNameType;
26 typedef std::vector<int>::iterator SecondNameType;
27 typedef std::vector<int>::iterator ThirdNameType;
28
29 int main()
30 {
31 std::vector<int>();
32 auto it = MACRO(First, Name, Second, Name, Third, Name);
33 return 0;
34 }
这会产生大量与使用逗号有关的错误,开头是:
test.cpp:在函数“int main()”中: src/boost/boost/preprocessor/punctuation/comma.hpp:19:27: 错误: ',' 标记之前的预期主表达式 # 定义 BOOST_PP_COMMA() ,
【问题讨论】:
-
我会改用
MACRO((First, Set), (Second, Type), (Third, Thing))并使用BOOST_PP_TUPLE_*。 -
@chris 谢谢,我不知道这一点。但是如何解决“不允许递归”的问题呢?
-
@Jason:无论如何都要递归:文件 x.h:
#include "x.h"... -
@KerrekSB 我不确定我是否遵循。你的意思是我应该递归
#include? -
@Jason,Boost 提供了用于枚举序列的实用程序。看看boost.org/doc/libs/1_55_0/libs/preprocessor/doc/index.html