Search code examples
c++c++14boost-fusionboost-spirit-x3

Matching a sequence of two integers into an `std::pair<int, int>`


I'm trying to use Boost.Sprit x3 to match a sequence of two integers into an std::pair<int, int>. Judging by the documentation, the following code should compile:


#include <string>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>

int main()
{
    using namespace boost::spirit::x3;

    std::string input("1 2");
    std::pair<int, int> result;
    parse(input.begin(), input.end(), int_ >> int_, result);
}

melpon.org link


However, it only matches the first integer. If I change std::pair<int, int> result; to int result; and then print result, I get 1 as my output.

Why is that happening? Isn't int_ >> int_ the correct way of defining a parser that matches (and sets as attributes) two integers?


Solution

  • Actually, @T.C. 's comment of including <boost/fusion/adapted/std_pair.hpp> is only enough to silence the compiler, not to correctly parse your string. I also had to change the x3::parse() for a x3::phrase_parse() that skips over whitespace:

    #include <iostream>
    #include <string>
    #include <boost/config/warning_disable.hpp>
    #include <boost/spirit/home/x3.hpp>
    #include <boost/fusion/adapted/std_pair.hpp>
    
    int main()
    {
        namespace x3 = boost::spirit::x3;
    
        std::string input("1 2");
        std::pair<int, int> result;
        auto ok = x3::phrase_parse(input.begin(), input.end(), x3::int_ >> x3::int_, x3::space, result);
        std::cout << std::boolalpha << ok << ": ";
        std::cout << result.first << ", " << result.second;
    }
    

    Live Example

    Note that I also replaced your using namespace boost::spirit::x3 with a namespace alias x3. This will keep the readability but will prevent from dumping the huge of amount of Boost.Spirit symbols into your code.