我已经编写了一些预处理程序指令来为类生成函数。随着Boost 1.55一切正常。当我尝试更改为Boost 1.57时,我遇到了一些奇怪的编译错误。
该计划是:
#include <iostream>
#include <boost/preprocessor.hpp>
#ifndef BOOST_PP_VARIADICS
#define BOOST_PP_VARIADICS
#endif
#define ADD_CONST_REF(op, data, elem) elem const &
#define FUNCTION_DECL(r, data, tup) \
double BOOST_PP_TUPLE_ELEM(0, tup) \
BOOST_PP_IF(BOOST_PP_LIST_IS_NIL(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(1, tup))), \
(), \
BOOST_PP_SEQ_TO_TUPLE( \
BOOST_PP_SEQ_TRANSFORM(ADD_CONST_REF, \
_, \
BOOST_PP_TUPLE_TO_SEQ(BOOST_PP_LIST_TO_TUPLE(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(1, tup)))) \
) \
) \
) \
const;
#define MY_FUNCTIONS(seq) \
BOOST_PP_SEQ_FOR_EACH(FUNCTION_DECL, _, seq)
class Foo
{
public:
MY_FUNCTIONS( \
((a, (int))) \
((b) ) \
)
};
#define ADD_ARG(op, data, elem) elem const & BOOST_PP_CAT(a_, elem)
#define MY_FUNCTION_BEGIN(tup) \
double Foo::BOOST_PP_TUPLE_ELEM(0, tup) \
BOOST_PP_IF(BOOST_PP_LIST_IS_NIL(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(1, tup))), \
(), \
BOOST_PP_SEQ_TO_TUPLE( \
BOOST_PP_SEQ_TRANSFORM( \
ADD_ARG, \
_, \
BOOST_PP_TUPLE_TO_SEQ(BOOST_PP_LIST_TO_TUPLE(BOOST_PP_TUPLE_TO_LIST(BOOST_PP_TUPLE_ELEM(1, tup)))) \
) \
) \
) const \
{
#define MY_FUNCTION_END() }
MY_FUNCTION_BEGIN((a, (int)))
{
std::cout << "Foo::a(" << a_int << ")\n";
}
MY_FUNCTION_END()
MY_FUNCTION_BEGIN((b))
{
std::cout << "Foo::b()\n";
}
MY_FUNCTION_END()
int main()
{
Foo f;
f.a(42);
f.b();
return 0;
}
使用gcc 4.9.1我得到以下输出:
test.cpp:33:1: error: macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given
)
^
test.cpp:33:1: error: macro "BOOST_PP_VARIADIC_ELEM_2" requires 4 arguments, but only 2 given
test.cpp:60:1: error: macro "BOOST_PP_SEQ_ELEM_III" requires 2 arguments, but only 1 given
MY_FUNCTION_BEGIN((b))
^
test.cpp:60:1: error: macro "BOOST_PP_VARIADIC_ELEM_2" requires 4 arguments, but only 2 given
clang 3.5.0对我说:
test.cpp:30:3: error: too few arguments provided to function-like macro invocation
MY_FUNCTIONS( \
^
test.cpp:25:25: note: expanded from macro 'MY_FUNCTIONS'
BOOST_PP_SEQ_FOR_EACH(FUNCTION_DECL, _, seq)
^
..../boost.1_57_0/boost/preprocessor/seq/for_each.hpp:26:67: note: expanded from macro 'BOOST_PP_SEQ_FOR_EACH'
# define BOOST_PP_SEQ_FOR_EACH(macro, data, seq) BOOST_PP_FOR((macro, data, seq (nil)), BOOST_PP_SEQ_FOR_EACH_P, BOOST_PP_SEQ_FOR_EACH_O, BOOST_PP_SEQ_FOR_EACH_M)
^
..../boost.1_57_0/boost/preprocessor/repetition/detail/for.hpp:22:78: note: expanded from macro 'BOOST_PP_FOR_1'
# define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p(2, s)), s, p, o, m)
^
note: (skipping 18 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
packages/boost/boost_i4/boost/preprocessor/seq/elem.hpp:22:39: note: expanded from macro 'BOOST_PP_SEQ_ELEM'
# define BOOST_PP_SEQ_ELEM(i, seq) BOOST_PP_SEQ_ELEM_I(i, seq)
^
packages/boost/boost_i4/boost/preprocessor/seq/elem.hpp:41:45: note: expanded from macro 'BOOST_PP_SEQ_ELEM_I'
# define BOOST_PP_SEQ_ELEM_I(i, seq) BOOST_PP_SEQ_ELEM_II(BOOST_PP_SEQ_ELEM_ ## i seq)
^
packages/boost/boost_i4/boost/preprocessor/seq/elem.hpp:43:62: note: expanded from macro 'BOOST_PP_SEQ_ELEM_II'
# define BOOST_PP_SEQ_ELEM_II(im) BOOST_PP_SEQ_ELEM_III(im)
^
packages/boost/boost_i4/boost/preprocessor/seq/elem.hpp:44:13: note: macro 'BOOST_PP_SEQ_ELEM_III' defined here
# define BOOST_PP_SEQ_ELEM_III(x, _) x
在我改为Boost 1.57后,有谁知道问题是什么?
答案 0 :(得分:0)
我发现this trac ticket表明这可能是由于BOOST_PARAMETER_CONSTRUCTOR()
没有为可选参数设置默认参数(与BOOST_PARAMETER_FUNCTION()
不同)。
1.57的发行说明确实注意到Boost :: Preprocessor中有关可变辅助的一些更改,因此您可以查看the 1.57 docs以查看其中是否有任何内容可以帮助您。
答案 1 :(得分:0)
我找到了使用C ++ 11可变参数宏的工作解决方案。这是:
#include <iostream>
#include <string>
#ifndef BOOST_PP_VARIADICS
#define BOOST_PP_VARIADICS
#endif
#include <boost/preprocessor.hpp>
#define FUNCTION_DECL_IMPL_1(name) \
double name() const;
#define FUNCTION_ARGS_IMPL_1(arg1) arg1 const &
#define FUNCTION_ARGS_IMPL_2(arg1, arg2) arg1 const &, arg2 const &
#define FUNCTION_ARGS_IMPL_3(arg1, arg2, arg3) arg1 const &, arg2 const &, arg3 const &
#define FUNCTION_ARGS(...) \
BOOST_PP_OVERLOAD(FUNCTION_ARGS_IMPL_, __VA_ARGS__)(__VA_ARGS__)
#define FUNCTION_DECL_IMPL_2(name, args) \
double name( \
FUNCTION_ARGS(BOOST_PP_TUPLE_REM()args) \
) const;
#define FUNCTION_DECL_VAR(...) \
BOOST_PP_OVERLOAD(FUNCTION_DECL_IMPL_, __VA_ARGS__)(__VA_ARGS__)
#define FUNCTION_DECL(r, data, tup) \
FUNCTION_DECL_VAR(BOOST_PP_TUPLE_REM()tup)
#define MY_FUNCTIONS(seq) \
BOOST_PP_SEQ_FOR_EACH(FUNCTION_DECL, _, seq)
class Foo
{
public:
MY_FUNCTIONS( \
((a, (int))) \
((b)) \
((c, (double, std::string))) \
)
};
#define MY_FUNCTION_BEGIN_IMPL_1(name) \
double Foo::name() const {
#define FUNCTION_ARGS2_IMPL_1(arg1) arg1 const & a_arg1
#define FUNCTION_ARGS2_IMPL_2(arg1, arg2) arg1 const & a_arg1, arg2 const & a_arg2
#define FUNCTION_ARGS2_IMPL_3(arg1, arg2, arg3) arg1 const & a_arg1, arg2 const & a_arg2, arg3 const & a_arg3
#define FUNCTION_ARGS2(...) \
BOOST_PP_OVERLOAD(FUNCTION_ARGS2_IMPL_, __VA_ARGS__)(__VA_ARGS__)
#define MY_FUNCTION_BEGIN_IMPL_2(name, args) \
double Foo::name( \
FUNCTION_ARGS2(BOOST_PP_TUPLE_REM()args) \
) const {
#define MY_FUNCTION_BEGIN(...) \
BOOST_PP_OVERLOAD(MY_FUNCTION_BEGIN_IMPL_, __VA_ARGS__)(__VA_ARGS__)
#define MY_FUNCTION_END() }
MY_FUNCTION_BEGIN(a, (int))
{
std::cout << "Foo::a(" << a_arg1 << ")\n";
}
MY_FUNCTION_END()
MY_FUNCTION_BEGIN(b)
{
std::cout << "Foo::b()\n";
}
MY_FUNCTION_END()
MY_FUNCTION_BEGIN(c, (double, std::string))
{
std::cout << "Foo::c(" << a_arg1 << "," << a_arg2 << ")\n";
}
MY_FUNCTION_END()
int main()
{
Foo f;
f.a(42);
f.b();
f.c(3.1415, "wohaa");
return 0;
}