从Boost 1.49移动到Boost 1.54时Boost :: Spirit编译器错误

时间:2014-01-07 17:54:34

标签: c++ boost boost-spirit

我有一个用Boost :: Spirit编写的简单语法,定义如下:

template <typename Iterator_T>
struct my_grammar :
qi::grammar<Iterator_T, vector<basic_value_t>(), qi::locals<size_t> >
{
  my_grammar();

  qi::rule<Iterator_T, vector<basic_value_t>(), qi::locals<size_t> > start;
  qi::rule<Iterator_T, basic_value_t(), qi::locals<size_t> > ptuple;
};

template <typename Iterator_T>
my_grammar<Iterator_T>::
my_grammar() : my_grammar<Iterator_T>::base_type(start), start(), ptuple() {
  start = (*ptuple);

  ptuple
    = (qi::byte_ >>
       qi::omit[qi::byte_[qi::_a = qi::_1]] >>
       qi::repeat(qi::_a)[qi::byte_])
    ;
}

basic_value_t定义为:

struct basic_value_t {
  uint8_t type;        
  vector<uint8_t> val;
};

包含在BOOST_FUSION_ADAPT_STRUCT中:

BOOST_FUSION_ADAPT_STRUCT
(
 basic_value_t,
 (std::uint8_t, type)
 (std::vector<std::uint8_t>, val)
)

然后使用以下语句初始化语法:

my_grammar<vector<uint8_t>::const_iterator> grammar;

在使用boost 1.54编译代码时,我遇到错误。但是,如果我使用boost 1.49编译相同的代码,我不会收到错误。我可以想象,我有一个微妙的错误,当我移动到更新版本的Boost时,它只会显示出来。

以下是非常长的错误消息序列的最后一部分的错误。

/home/making/Dev/filename.cpp:498:51: required from here
/usr/include/boost/fusion/view/transform_view/detail/value_of_impl.hpp:36:79: error: no type named ‘type’ in ‘struct boost::mpl::apply<boost::fusion::detail::apply_transform_result<boost::spirit::traits::build_attribute_sequence<boost::fusion::cons<boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::fusion::cons<boost::spirit::qi::omit_directive<boost::spirit::qi::action<boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::assign_eval, boost::fusion::vector<boost::spirit::local_variable<0>, boost::spirit::argument<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > > > >, boost::fusion::cons<boost::spirit::qi::lazy_directive<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::repeat> >, boost::spirit::local_variable<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::spirit::unused_type>, boost::fusion::nil> > >, boost::spirit::context<boost::fusion::cons<ccss_protocols::iec61850::basic_value_t&, boost::fusion::nil>, boost::fusion::vector1<long unsigned int> >, boost::spirit::traits::sequence_attribute_transform, __gnu_cxx::__normal_iterator<const unsigned char*, std::vector<unsigned char> >, boost::spirit::qi::domain>::element_attribute>, boost::spirit::qi::lazy_directive<boost::phoenix::actor<boost::phoenix::composite<boost::phoenix::detail::function_eval<1>, boost::fusion::vector<boost::phoenix::value<boost::spirit::terminal<boost::spirit::tag::repeat> >, boost::spirit::local_variable<0>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > >, boost::spirit::qi::any_binary_parser<boost::spirit::qi::detail::integer<8>, (boost::spirit::endian::endianness)2, 8>, boost::spirit::unused_type>, mpl_::na, mpl_::na, mpl_::na, mpl_::na>’
             typedef typename mpl::apply<transform_type, value_type>::type type;
                                                                           ^
make[2]: *** [CMakeFiles/ccss-protocols-iec61850.dir/src/goose/application-layer.cpp.o] Error 1

提前感谢您考虑此错误。

1 个答案:

答案 0 :(得分:4)

定义

#define BOOST_SPIRIT_USE_PHOENIX_V3

修复它,如链接样本中所示(感谢@cv_and_he)

在现有答案中记录了原因:


以下是完整工作样本以供将来参考:生活在 Coliru

#include <iostream>
#include <string>
#include <vector>

//#define BOOST_SPIRIT_USE_PHOENIX_V3

#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;

struct basic_value_t {
  uint8_t type;        
  std::vector<uint8_t> val;
};


BOOST_FUSION_ADAPT_STRUCT
(
 basic_value_t,
 (std::uint8_t, type)
 (std::vector<std::uint8_t>, val)
)

template <typename Iterator_T>
struct my_grammar :
qi::grammar<Iterator_T, std::vector<basic_value_t>() >
{
  my_grammar();

  qi::rule<Iterator_T, std::vector<basic_value_t>() > start;
  qi::rule<Iterator_T, basic_value_t(), qi::locals<size_t> > ptuple;
};

template <typename Iterator_T>
my_grammar<Iterator_T>::
my_grammar() : my_grammar<Iterator_T>::base_type(start), start(), ptuple() {
  start = (*ptuple);

  ptuple
    %= (qi::byte_ >>
       qi::omit[qi::byte_[qi::_a = qi::_1]] >>
       qi::repeat(qi::_a)[qi::byte_])
    ;
}

int main()
{
    std::vector<std::uint8_t> test = {1,3,1,2,3};
    my_grammar<std::vector<std::uint8_t>::const_iterator> grammar;

    std::vector<std::uint8_t>::const_iterator iter = test.begin(), end = test.end();

    std::vector<basic_value_t> parsed_value_vector;

    bool result = qi::parse(iter,end,grammar,parsed_value_vector);

    if(result && iter==end)
    {
        std::cout << "Success: Type=" << static_cast<int>(parsed_value_vector[0].type) << "; Vals= ";
        for(int num : parsed_value_vector[0].val)
            std::cout << num << ".";
        std::cout << std::endl;
    }
    else
    {
        std::cout << "Failure." << std::endl;
    }
}