2012-07-12 4 views
9

Zum Beispiel ist Folgendes möglich:Erhalten Sie einen Zeiger auf den STL-Container, auf den ein Iterator verweist?

std::set<int> s; 
std::set<int>::iterator it = s.begin(); 

Ich frage mich, ob das Gegenteil möglich ist, sagen wir,

std::set<int>* pSet = it->**getContainer**(); // something like this... 
+0

Ich bin interessiert zu wissen, warum Sie das wollen. – chris

+0

Was ich versuche ist, den Zustand des Iterators während einer Traversierung (einer anderen Datenstruktur) zu speichern, damit ich den Iterator beim nächsten Besuch inkrementieren kann. Wenn das obige möglich ist, muss ich nicht den Verweis/Zeiger auf den Container selbst halten, sondern nur den Zeiger auf diesen Iterator. –

Antwort

13

Nein, es gibt keine tragbare Art und Weise, dies zu tun.

Ein Iterator darf nicht einmal einen Verweis auf den Container haben. Zum Beispiel könnte eine Implementierung T* als iterator Typ für beide std::array<T, N> und std::vector<T> verwenden, da beide ihre Elemente als Arrays speichern.

Darüber hinaus sind Iteratoren viel allgemeiner als Container, und nicht alle Iteratoren zeigen in Container (beispielsweise gibt es Eingabe- und Ausgabe-Iteratoren, die aus Streams lesen und schreiben).

+0

Das ist alt, aber ich habe eine sehr kleine Frage. Unter der Annahme, dass ein Iterator (nicht notwendigerweise von STL) aus einem Container stammte, kann er einen Zeiger/Verweis auf seinen Ursprungscontainer besitzen oder nicht. Aber wenn das der Fall ist, dann sind der Typ des Containers und der Container selbst dem Benutzer des Iterators absolut bekannt, nicht wahr? Es sei denn, der Zeiger/Verweis auf den Container ist natürlich als privat definiert, aber warum sollte der Programmierer das verbergen wollen? – Mark

5

Nein. Sie müssen sich den Container merken, aus dem ein Iterator stammt, als Sie den Iterator gefunden haben. Ein möglicher Grund für diese Einschränkung ist, dass Zeiger gültige Iteratoren sein sollen und es keinen Weg gibt, einen Zeiger zu fragen, woher er kommt (zB wenn man 4 Elemente in ein Array zeigt, wie aus diesem Zeiger allein) Können Sie sagen, wo der Anfang des Arrays ist?).

2

Es ist möglich mit mindestens einem der std Iteratoren und einige Tricks. Der std::back_insert_iterator benötigt einen Zeiger auf den Container, um seine push_back-Methode aufzurufen. Außerdem ist dieser Zeiger nur protected. Diese

#include <iterator> 

template <typename Container> 
struct get_a_pointer_iterator : std::back_insert_iterator<Container> { 
    typedef std::back_insert_iterator<Container> base; 
    get_a_pointer_iterator(Container& c) : base(c) {} 
    Container* getPointer(){ return base::container;} 
}; 

#include <iostream> 
int main() { 
    std::vector<int> x{1}; 
    auto p = get_a_pointer_iterator<std::vector<int>>(x); 
    std::cout << (*p.getPointer()).at(0); 
} 

ist natürlich keine praktische Verwendung, sondern lediglich ein Beispiel für eine std Iterator, der in der Tat trägt einen Zeiger auf seinen Behälter, wenn auch ein ganz besonderes (z. B. Erhöhung eines std::back_insert_iterator ist ein noop). Der entscheidende Punkt bei der Verwendung von Iteratoren ist nicht zu wissen, woher die Elemente kommen. Wenn Sie andererseits einen Iterator wünschen, mit dem Sie einen Zeiger auf den Container erhalten, können Sie einen schreiben.

Verwandte Themen