【问题标题】:Boost preprocessor program won't compile after change from Boost 1.55 to 1.57从 Boost 1.55 更改为 1.57 后,Boost 预处理器程序将无法编译
【发布时间】:2023-03-05 09:54:01
【问题描述】:

我已经编写了一些预处理器指令来为类生成函数。使用 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 后出现了什么问题?

【问题讨论】:

    标签: c++ boost boost-preprocessor


    【解决方案1】:

    我发现this trac ticket 这表明这可能是由于BOOST_PARAMETER_CONSTRUCTOR() 没有为可选参数采用默认参数(与BOOST_PARAMETER_FUNCTION() 不同)。

    1.57 的发行说明确实记录了 Boost::Preprocessor 中关于可变参数支持的一些更改,因此也许您可以查看the 1.57 docs 以查看其中是否有任何帮助。

    【讨论】:

      【解决方案2】:

      我找到了使用 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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-01-10
        • 1970-01-01
        • 1970-01-01
        • 2011-11-29
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多