eigenen iterator implementieren
-
Hallo NG,
Ich habe eine Klasse, die intern eine std::map<unsigned int, foo*> benutzt.
Jetzt würde ich nach außen gerne einen Iterator über die Keys (also unsigned int) der map herausgeben. Also nicht den Iterator der Map direkt weitergeben, weil dieser ja ein Iterator über pair<unsigned int, foo*> ist.
Der Nutzer der Klasse soll keine Möglichkeit haben ein Objekt von foo* zu bekommen, außer über die öffentlichen Methoden meiner Klasse.Ist dies möglich?
Ciao
TimoPS: Es sollte ein const iterator sein, weil ich eine Änderung der Schlüsselwerte nicht zulassen will.
-
Sicher ist das möglich. Du musst einfach eine Klasse schreiben, die intern einen std:
:const_iterator hat. Dann musst du noch die nötigen Operatoren wie ++, --, ==, != und * implementieren. Ein paar typedefs wird's auch noch brauchen.
-
Stefan schrieb:
Sicher ist das möglich. Du musst einfach eine Klasse schreiben, die intern einen std:
:const_iterator hat. Dann musst du noch die nötigen Operatoren wie ++, --, ==, != und * implementieren. Ein paar typedefs wird's auch noch brauchen.Uff das verstehe ich jetzt nicht ganz. Wie gesagt ich möchte ja nicht den Iterator der Map weitergeben, da dieser als Ergebnis ja ein pair hat.
Aber ich glaube ich komme einfach nicht drauf, was ich tun muss.Ciao
Timo
-
horscht2999 schrieb:
Uff das verstehe ich jetzt nicht ganz. Wie gesagt ich möchte ja nicht den Iterator der Map weitergeben, da dieser als Ergebnis ja ein pair hat.
Aber ich glaube ich komme einfach nicht drauf, was ich tun muss.Du weisst was ein iterator ist?
Im grossen und ganzen ist ein iterator wie ein Zeiger. Denke dabei einmal an char* fuer c strings.
Du brauchst einen operator++ und --. Damit du zum naechsten und zum vorherigen Element kommst. Dann natuerlich einen operator* um das Element selber zu bekommen. Und dann noch einen operator-> um eine methode fuer das Element aufzurufen (wenn das bei dir immer nur int ist, ist es natuerlich nicht notwendig).
Das alles kann dir map::iterator aber schon bieten. Du verwendest den map::iterator intern in deiner iterator klasse und leitest deine funktionalitaet an den map::iterator weiter und biegst die sachen um die du anders haben willst. der operator++ funktioniert bei dir und map::iterator ja gleich. Dagegen willst du dass der operator* bei dir einen int statt einem pair liefert - hier musst du also umbiegen und deinem operator* eben den first von dem pair liefern lassen...
-
Ah alles klar, jetzt hats geklingelt. Danke
-
horscht2999 schrieb:
Ich habe eine Klasse, die intern eine std::map<unsigned int, foo*> benutzt.
Jetzt würde ich nach außen gerne einen Iterator über die Keys (also unsigned int) der map herausgeben.eine schöne Anwendung für den boost.transform_iterator:
#include <iostream> #include <algorithm> // copy #include <map> #include <functional> // std::unary_function<> #include <iterator> // ostream_iterator #include <boost/iterator/transform_iterator.hpp> class Klasse { struct foo { int m_nix; }; struct PairToUint : std::unary_function< std::map< unsigned int, foo* >::value_type, unsigned int > { result_type operator()( const argument_type& x ) const { return x.first; } }; public: typedef boost::transform_iterator< PairToUint, std::map< unsigned int, foo* >::const_iterator > const_iterator; const_iterator begin() const { return const_iterator( m_foos.begin() ); } const_iterator end() const { return const_iterator( m_foos.end() ); } Klasse() : m_foos() { m_foos[3] = 0; m_foos[7] = 0; m_foos[4] = 0; } private: std::map< unsigned int, foo* > m_foos; }; int main() { using namespace std; Klasse objekt; // ... copy( objekt.begin(), objekt.end(), ostream_iterator< unsigned int >( cout << "Die Keys: ", " " ) ); cout << endl; return 0; }Gruß
Werner
-
Werner Salomon schrieb:
eine schöne Anwendung für den boost.transform_iterator...
Gruß
WernerWow genau sowas habe ich gesucht. Habs zwar selbst hinbekommen, aber da ich Boost eh verwende, wird das jetzt so eingebaut.
Vialen Dank!!!
Ciao
Timo