【问题标题】:boost spirit skipper - compile-time error提升精神船长 - 编译时错误
【发布时间】:2014-03-07 11:53:39
【问题描述】:

我有以下代码:

#include <boost/fusion/include/define_struct.hpp>
#include <boost/spirit/include/qi.hpp>

#include <iostream>
#include <string>

BOOST_FUSION_DEFINE_STRUCT(
  (), foo,
  (int, bar)
  (int, baz)
)

template <typename Iterator>
struct parser : boost::spirit::qi::grammar<Iterator, foo(), boost::spirit::qi::ascii::space_type>
{
  parser() : parser::base_type(start)
  {
    start %= boost::spirit::qi::int_ >> boost::spirit::qi::int_;
  }

  boost::spirit::qi::rule<Iterator, foo(), boost::spirit::qi::ascii::space_type> start;
};

int main()
{
  const std::string input_data("0 1");

  foo instance;
  auto itr = input_data.begin();
  auto end = input_data.end();
  parser<decltype(itr)> g;
  bool res = boost::spirit::qi::phrase_parse(
    itr
    , end
    , g
    , (
        boost::spirit::ascii::space
        | ("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >> boost::spirit::qi::eol | boost::spirit::qi::blank)
      )
    , instance
  );
  if (res && itr == end)
  {
    std::cout << "Parsing succeeded \n";
    std::cout << instance.bar << ' ' << instance.baz << '\n';
  }
  else
  {
    std::cout << "Parsing failed \n";
  }
}

它给了我以下错误:

1>e:\libs\boost_1_54_0\boost\spirit\home\qi\nonterminal\rule.hpp(303): error C2664: 'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const' : cannot convert parameter 4 from 'const skipper_type' to 'const boost::spirit::qi::char_class<Tag> '
1>          with
1>          [
1>              R=bool,
1>              T0=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>> &,
1>              T1=const std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>> &,
1>              T2=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::fusion::vector0<>> &,
1>              T3=const boost::spirit::qi::char_class<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>> &
1>          ]
1>          and
1>          [
1>              Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1>          ]
1>          Reason: cannot convert from 'const skipper_type' to 'const boost::spirit::qi::char_class<Tag>'
1>          with
1>          [
1>              Tag=boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              T1=`anonymous-namespace'::foo (void),
1>              T2=boost::spirit::ascii::space_type,
1>              T3=boost::spirit::unused_type,
1>              T4=boost::spirit::unused_type,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\reference.hpp(43) : see reference to function template instantiation 'bool boost::spirit::qi::rule<Iterator,T1,T2,T3,T4>::parse<Context,Skipper,Attribute>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              T1=`anonymous-namespace'::foo (void),
1>              T2=boost::spirit::ascii::space_type,
1>              T3=boost::spirit::unused_type,
1>              T4=boost::spirit::unused_type,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(165) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,boost::spirit::context<Attributes,Locals>,skipper_type,Attr>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Subject=const boost::spirit::qi::rule<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,`anonymous-namespace'::foo (void),boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Attributes=boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,
1>              Locals=boost::spirit::locals<>,
1>              Attr=`anonymous-namespace'::foo,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(165) : see reference to function template instantiation 'bool boost::spirit::qi::reference<Subject>::parse<Iterator,boost::spirit::context<Attributes,Locals>,skipper_type,Attr>(Iterator &,const Iterator &,Context &,const Skipper &,Attribute &) const' being compiled
1>          with
1>          [
1>              Subject=const boost::spirit::qi::rule<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,`anonymous-namespace'::foo (void),boost::spirit::ascii::space_type,boost::spirit::unused_type,boost::spirit::unused_type>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Attributes=boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,
1>              Locals=boost::spirit::locals<>,
1>              Attr=`anonymous-namespace'::foo,
1>              Context=boost::spirit::context<boost::fusion::cons<`anonymous-namespace'::foo &,boost::fusion::nil>,boost::spirit::locals<>>,
1>              Skipper=skipper_type,
1>              Attribute=`anonymous-namespace'::foo
1>          ]
1>          e:\libs\boost_1_54_0\boost\spirit\home\qi\parse.hpp(197) : see reference to function template instantiation 'bool boost::spirit::qi::phrase_parse<Iterator,Expr,Skipper,Attr>(Iterator &,Iterator,const Expr &,const Skipper &,boost::spirit::qi::skip_flag,Attr &)' being compiled
1>          with
1>          [
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Expr=parser<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>,
1>              Skipper=boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,2>,
1>              Attr=`anonymous-namespace'::foo
1>          ]
1>          e:\work\projects\src\min\min\main.cpp(13803) : see reference to function template instantiation 'bool boost::spirit::qi::phrase_parse<std::_String_const_iterator<_Mystr>,parser<Iterator>,boost::proto::exprns_::expr<Tag,Args,Arity>,`anonymous-namespace'::foo>(Iterator &,Iterator,const Expr &,const Skipper &,Attr &)' being compiled
1>          with
1>          [
1>              _Mystr=std::_String_val<std::_Simple_types<char>>,
1>              Iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>,
1>              Tag=boost::proto::tagns_::tag::bitwise_or,
1>              Args=boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,
1>              Arity=2,
1>              Expr=parser<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>,
1>              Skipper=boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::space,boost::spirit::char_encoding::ascii>>,0> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::bitwise_or,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::shift_right,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<const char (&)[3]>,0>,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::dereference,boost::proto::argsns_::list1<const boost::proto::exprns_::expr<boost::proto::tagns_::tag::minus,boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::standard::char_> ,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &>,1> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::eol>,0> &>,2> &,const boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::tag::char_code<boost::spirit::tag::blank,boost::spirit::char_encoding::standard>>,0> &>,2> &>,2>,
1>              Attr=`anonymous-namespace'::foo
1>          ]

这是添加的结果

("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >> boost::spirit::qi::eol | boost::spirit::qi::blank)

我做错了什么?我该如何解决?

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi


    【解决方案1】:

    确实,您的船长类型不正确。

    改变它例如:

    #include <boost/fusion/include/define_struct.hpp>
    #include <boost/spirit/include/qi.hpp>
    
    #include <iostream>
    #include <string>
    
    namespace qi = boost::spirit::qi;
    
    BOOST_FUSION_DEFINE_STRUCT(
      (), foo,
      (int, bar)
      (int, baz)
    )
    
    template <typename Iterator, typename Skipper>
        struct parser : qi::grammar<Iterator, foo(), Skipper>
    {
        parser() : parser::base_type(start)
        {
            start %= qi::int_ >> qi::int_;
        }
    
        qi::rule<Iterator, foo(), Skipper> start;
    };
    
    int main()
    {
      const std::string input_data("0 1");
    
      foo instance;
      auto itr = input_data.begin();
      auto end = input_data.end();
    
      qi::rule<decltype(itr)> skipper = 
              qi::ascii::space 
            | ("//" >> *(qi::char_ - qi::eol) >> qi::eol | qi::blank);
    
      parser<decltype(itr), decltype(skipper)> g;
    
      bool res = qi::phrase_parse(itr, end, g, skipper, instance);
    
      if (res && itr == end)
      {
          std::cout << "Parsing succeeded \n";
          std::cout << instance.bar << ' ' << instance.baz << '\n';
      }
      else
      {
          std::cout << "Parsing failed \n";
      }
    }
    

    Live On Coliru

    【讨论】:

    • 你能给我你的电子邮件/Skype,好吗?我在您的 StackExchange 个人资料中没有看到此类信息
    • @FrozenHeart 其他人已经能够找到它:) 一般来说,我更喜欢围绕 SO 进行“支持”活动。我当然可以在我的个人资料中添加一个“捐赠”按钮 :)
    【解决方案2】:

    您的船长类型仍然是boost::spirit::qi::ascii::space_type,尽管您将船长更改为

    boost::spirit::ascii::space
    | ("//" >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol) >>   boost::spirit::qi::eol | boost::spirit::qi::blank)
    

    只需将您的规则放在一个单独的船长组件中并使用它的类型。快速搜索给出了这个例子https://stackoverflow.com/a/8534840/2524462 如何做到这一点。

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-10
      • 1970-01-01
      相关资源
      最近更新 更多