How to use boost::tuple as attribute in a boost::spirit rule?

人走茶凉 提交于 2019-12-07 02:11:46

问题


I have the following rule in boost::spirit:

typedef boost::tuple<int, int> Entry;
qi::rule<Iterator, Entry(), Skipper> entry;
entry = qi::int_ >> qi::int_;

But the second int is not written into the tuple. Is there a way to make it work without having to use boost::fusion::tuple?

It works if I use std::pair, so why can't I use boost::tuple?

Here is a full compiling example:

#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/tuple.hpp>
#include <boost/tuple/tuple.hpp>
namespace qi = boost::spirit::qi;

// works:
// #include <boost/fusion/include/std_pair.hpp>
// typedef std::pair<int, int> Entry;

// doesn't work:
typedef boost::tuple<int, int> Entry;

template <typename Iterator, typename Skipper>
struct MyGrammar : qi::grammar<Iterator, Entry(), Skipper> {
  MyGrammar() : MyGrammar::base_type(entry) {
    entry = qi::int_ >> qi::int_;
  }
  qi::rule<Iterator, Entry(), Skipper> entry;
};

int main() {
  const std::string in = "1 3";
  typedef std::string::const_iterator It;
  It it = in.begin();

  Entry entry;
  MyGrammar<It, qi::space_type> gr;
  if (qi::phrase_parse(it, in.end(), gr, qi::space, entry)
      && it == in.end()) {
    std::cout << boost::get<0>(entry) << "," << boost::get<1>(entry) << std::endl;
  }
  return 0;
}

回答1:


In order for Spirit to recognize boost::tuple<> as a valid Fusion sequence, you need to include an additional header:

#include <boost/fusion/include/boost_tuple.hpp>

This is somewhat loosely hinted at in the docs here.



来源:https://stackoverflow.com/questions/10692071/how-to-use-boosttuple-as-attribute-in-a-boostspirit-rule

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!