2009-06-30 5 views
7

Ich habe meine eigene Containervorlage mit einem Iterator geschrieben. Wie implementiere ich const_iterator?C++: Wie schreibe ich einen Const_iterator?

template <class T> 
class my_container { 
private: 
    ... 

public: 
    my_container() : ... { } 
    ~my_container() { } 

    class iterator : public std::iterator<std::bidirectional_iterator_tag, T> { 
    public: ... 

Antwort

4

Der einzige Unterschied sollte sein, dass, wenn Sie de-reference eine const iterator Sie eine konstante Referenz erhalten, anstatt eine Referenz auf das Objekt im Container.

+1

Was ist mit Methoden, die Iteratoren als Argumente oder Iteratoren zurückgeben? Ich muss sie für const_iterators überladen? Scheint wie ein Haufen wiederholten Code. –

+0

Iteratoren sollten in const_iterators konvertierbar sein, so dass Sie nicht überladen müssen, wenn Sie nur einen const_iterator benötigen. Sie tun dies für Funktionen wie begin(), end(), aber es gibt keinen Weg dazu, da dies auch Teil der Signatur der Methode ist. –

+2

@ Posco Grubb: Nein. Wenn Sie Methoden haben, die Iteratoren nehmen, dann template sie. Die Methode sollte für alles funktionieren, was wie ein Iterator funktioniert. Wenn die Methode einen Iterator und nicht einen Const_iterator erfordert, generiert der Compiler den entsprechenden Fehler. –

2

Ich finde den einfachsten Weg Iteratoren zu implementieren ist boost::iterator. Wenn Sie Ihre eigene Rolle wollen, denke ich, die Unterschrift sein sollte:

class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const T> { 

mit der Umsetzung der gleiche (vorausgesetzt, Sie reference_type verwenden und so weiter in Ihrer Funktion Unterschriften)

+0

konvertieren Ich war überrascht zu finden, dass iterator_traits :: const_iterator> :: value_type ist int, nicht int const (T, anstelle von const T in Ihrem Code). Ich denke mit const macht aber mehr Sinn. Wenn Sie jedoch mit den Standardcontainern übereinstimmen möchten, müssen Sie nicht-const. T verwenden. –

+0

Das Wichtige bei einem Const-Iterator ist, dass Sie ihn nicht zum Ändern der Sammlung verwenden können, die iteriert wird. Also, T oder const T & sind angemessen. Die Verwendung von const mit nur T ist nicht notwendig (da die Rückgabe eine Kopie ist) –

+0

Nun, wenn Sie angeben möchten, dass by-value nicht-const ist, müssen Sie alle Parameter angeben: class const_iterator: public std :: Iterator . Ich würde der Kürze halber (mit etwas mehr Schutz vor Zuweisungs-/Gleichheitsfehlern) anstelle der Übereinstimmung mit STL-Vektoren gehen, aber es ist eine schwierige Entscheidung vom Standpunkt des Designs. –

0

Roger Pate, value_types sind "einfach". Ich vermute, dass Sie das const sehen werden, wenn Sie iterator_traits :: const_iterator> :: reference betrachten, was meiner Meinung nach "const int &" sein wird.