Custom Iterator über vector mit boost::tuples



  • Hallo,

    ich konnte leider keine für mich brauchbare Hilfe ergoogeln und würde mich deshalb freuen wenn mir hier jemand weiterhelfen könnte.

    Ich habe einen stl container wie folgt definiert:

    typedef boost::tuple<int, Point_3, Color_3, Vector_3> IRGBNPoint;
    typedef std::vector<IRGBNPoint> IRGBNPointList;
    

    Weiterhin habe ich mir Iteratoren definiert die über meine Tuples im vector gehen:

    IRGBNPointList::iterator points_begin() { return _points->begin(); }
    IRGBNPointList::iterator points_end() { return _points->end(); }
    

    Was ich aber noch zusätzlich gerne hätte wären Iteratoren die mir über einen spezifischen Eintrag des Boost Tuples, also über jeden Point_3, Color_3 oder Vector_3 in meinem std::vector gehen. Für jeden Tip wie ich da rangehe wäre ich sehr dankbar.

    Viele Grüße


  • Mod

    template <typename T>
    struct Extractor {
        template <typename Tuple>
        constexpr decltype(auto) operator()(Tuple&& tup) {
            return std::get<T>(std::forward<Tuple>(tup));}
    };
    
    using iter = boost::transform_iterator<Extractor<Point_3>, IRGBNPointList::iterator>;
    


  • Danke Arcoth,

    das ist genau was ich brauche, nur leider noch etwas zu hoch für mich...! Ich bekomme in Deinem Beispiel für Zeile 4 die Fehler:

    error: C2062: type 'auto' unexpected

    und

    error: C3553: decltype expects an expression not a type

    Leider komme ich nicht dahinter was das Problem verursacht.


  • Mod

    Ach, du benutzt VC++....

    template <typename T>
    struct Extractor {
        template <typename Tuple>
        constexpr auto operator()(Tuple&& tup) ->  decltype(std::get<T>(std::forward<Tuple>(tup))) {
            return std::get<T>(std::forward<Tuple>(tup));} // Kann man mit einem Makro verschönern.
    };
    
    using iter = boost::transform_iterator<Extractor<Point_3>, IRGBNPointList::iterator>;
    

    Es könnte sein, dass get<T> Probleme macht. In dem Fall musst du stattdessen mit den Indexversionen arbeiten.



  • Danke nochmal Arcoth,

    hat mich noch viel Schweiß und Tränen gekostet und das Ergebnis ist noch nicht sehr befriedigend, aber ich habe etwas zum laufen gebracht dank Deiner Hilfe, ich poste mal wie, für eventuelle Leidensgenossen.

    Leider ist constexpr in Visual Studio 2013 noch nicht verfügbar, ob es ausschließlich daran lag kann ich nicht nachvollziehen, ich musste deshalb auf ein Templatelevel verzichten und einen Extractor für jeden meiner Tupleeinträge erzeugen:

    // Extrahiert ausschließlich den nullten Tuple Eintrag
    struct Extractor0 {
        template <typename Tuple>
        Point_3& operator()(Tuple&& tup) const {
            return tup.get<0>();}
    };
    
    typedef boost::transform_iterator<Extractor0, RGBNPointList::iterator, Point_3&> point_iter;
    

    Verwendet wird das Ganze dann so:

    point_iter points_begin() {
           Extractor0 m;
           return point_iter(_raw_points->begin(), m);
    }
    point_iter points_end() {
           Extractor0  m;
           return point_iter(_raw_points->end(), m);
    
    }
    

    _raw_points ist vom typ:

    typedef boost::tuple<Point_3, Point_3, Vector_3> RGBNPoint;
    typedef std::vector<RGBNPoint> RGBNPointList
    

Log in to reply