Search code examples
c++boost-spirit-qi

boost::spirit::qi::phrase_parser() into std::map error


The below code is to parse a "key=val;.." string into std::map and it fails to compile with the error:

Error C2146 : syntax error: missing '>' before identifier 'value_type'
Error C2039 : 'value_type': is not a member of 'std::pair,std::allocator,std::basic_string,std::allocator>>' c:\git\risk-engine-core_tcp\stage\boost-1.66.0-barclays-1\include\boost\spirit\home\support\container.hpp

It does not like the last parameter, "contents" (std::map), passed as a container.

Boost version is 1.66

namespace qi = boost::spirit::qi;

std::map<std::string,std::string> contents;
std::string::iterator first = str.begin();
std::string::iterator last  = str.end();

const bool result = qi::phrase_parse(first,last, 
*( *(qi::char_-"=")  >> qi::lit("=") >> *(qi::char_-";") >> -qi::lit(";") ),
 ascii::space, contents); 

Looking at the boost docs and stack overflow, I do not see any issue with the above code.


Solution

  • Did you include

    #include <boost/fusion/adapted/std_pair.hpp>
    

    Here's a working example with some improvement suggestions:

    Live On Coliru

    #include <boost/fusion/adapted/std_pair.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <map>
    #include <iomanip> // std::quoted
    
    namespace qi = boost::spirit::qi;
    
    int main() {
        std::string str("key = value");
        std::string::const_iterator first = str.begin();
        std::string::const_iterator last  = str.end();
    
        std::map<std::string, std::string> contents;
        bool const result = qi::phrase_parse(first,last, 
            *( *~qi::char_('=')  >> '=' >> *~qi::char_(';') >> -qi::lit(';') ),
             qi::ascii::space, contents); 
    
        if (result) {
            std::cout << "Parsed " << contents.size() << " elements\n";
            for (auto& [k,v] : contents) {
                std::cout << "\t" << std::quoted(k) << ": " << std::quoted(v) << "\n";
            }
        } else {
            std::cout << "Parse failed\n";
        }
    
        if (first != last)
            std::cout << "Remaining input unparsed: " << std::quoted(std::string(first, last)) << "\n";
    }
    

    Prints

    Parsed 1 elements
        "key": "value"