boost::spirit:qi permutation von attributen?



  • Hi,

    ich habe folgenden code der funktioniert:

    #include <boost/spirit/include/qi.hpp>
    #include <boost/fusion/include/std_pair.hpp>
    #include <iostream>
    int main(){
        using namespace boost::spirit::qi;
        std::string contents("1234 5678");
        std::vector<std::pair<int,double> > p;
        phrase_parse(
        contents.begin(), contents.end(), 
            *(int_>> double_),
            space , p
        );
    
        std::cout<<p[0].first<<" "<<p[0].second;
    }
    

    so klappt das auch ganz gut. leider muss ich in die selbe datenstruktur noch genau die umgedrehte reihenfolge später einlesen, das heißt ich möchte

    *(double_>> int_)
    

    aber alles was ich mir aus der docu rauslesen konnte funktionierte nicht in der art, das ich ungefähr 100KB fehlermeldungen hatte mit Typen die ungefähr 10 Bildschirmseiten lang waren 🤡.

    Ohne den Vektor hätte ich es "fast" zum Laufen gekriegt, indem ich mithilfe von phönix und actors folgendes geschrieben habe:

    double_[at_c<1>(_val) = _1] >> int_[at_c<0>(_val) = _1]
    

    aber die Ausgabe hinterher war 5678 5678. Mit vektor allerdings kamen die gruseligsten compilefehler die darauf hinausliefen, das den actors direkt ein std::vector übergeben wird.

    Hat jemand eine Ahnung, wie man das richtig macht?



  • Kann es sein, dass Du die Typen im std:: pair nicht nachgezogen hast?



  • Tachyon schrieb:

    Kann es sein, dass Du die Typen im std:: pair nicht nachgezogen hast?

    Ja. Genau das ist das Problem. Ich kann sie nicht nachziehen, weil sie im restlichen code so sein müssen.


  • Mod

    Mal solange drauf eingeprügelt bis es lief. Ist wahrscheinlich umständlicher als nötig und ich habe nicht wirklich Ahnung, was ich hier tue

    #include <boost/spirit/include/qi.hpp>
    #include <iostream>
    int main(){
        namespace spirit = boost::spirit;
        namespace qi = spirit::qi;
        namespace fusion = boost::fusion;
        std::string contents("1234 5678.9 5678.9 1234");
        std::vector<std::pair<int,double> > p;
        qi::phrase_parse(
            contents.begin(), contents.end(),
            *((qi::int_ - ( qi::int_ >> '.' )) >> qi::double_)[(
                [&p](fusion::vector<int,double> v, qi::unused_type, qi::unused_type)
                {
                    p.emplace_back(fusion::at_c<0>(v), fusion::at_c<1>(v));
                })] >>
            *(qi::double_ >> (qi::int_ - (qi::int_ >> '.')))[(
                [&p](fusion::vector<double,int> v, qi::unused_type, qi::unused_type)
                {
                    p.emplace_back(fusion::at_c<1>(v), fusion::at_c<0>(v));
                })],
            qi::space
        );
    
        std::cout<<p[0].first<<" "<<p[0].second<<'\n';
        std::cout<<p[1].first<<" "<<p[1].second<<'\n';
    }
    


  • Hmm. Ja, das sollte funktionieren. Ist natürlich maximal unelegant und ich hab keinen lambda support *seufz* muss ich wohl mit phoenix machen...


Anmelden zum Antworten