Namensräume
Varianten
Aktionen

Iterator-Bibliothek

Von cppreference.com
< cpp
 
 
Iterator-Bibliothek
Iterator-Konzepte
Iterator-Primitive
Algorithmus-Konzepte und Hilfsprogramme
Indirekte aufrufbare Konzepte
Gemeinsame Algorithmus-Anforderungen
(C++20)
(C++20)
(C++20)
Dienstprogramme
(C++20)
Iterator-Adapter
Bereichszugriff
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 

Iteratoren sind eine Verallgemeinerung von Zeigern, die es einem C++-Programm ermöglichen, mit verschiedenen Datenstrukturen (z. B. Containern und Ranges(seit C++20)) auf einheitliche Weise zu arbeiten. Die Iterator-Bibliothek stellt Definitionen für Iteratoren sowie Iterator-Traits, -Adapter und Hilfsfunktionen bereit.

Da Iteratoren eine Abstraktion von Zeigern sind, verallgemeinert ihre Semantik die meisten Zeigersemantiken in C++. Dies stellt sicher, dass jede Funktionsschablone, die Iteratoren verwendet, auch mit normalen Zeigern funktioniert.

Inhalt

[bearbeiten] Iterator-Kategorien

Es gibt fünf(bis C++17)sechs(seit C++17) Arten von Iteratoren: LegacyInputIterator, LegacyOutputIterator, LegacyForwardIterator, LegacyBidirectionalIterator, LegacyRandomAccessIterator und LegacyContiguousIterator(seit C++17). (Siehe auch LegacyIterator für die grundlegendste Iterator-Art.)

Anstatt durch bestimmte Typen definiert zu werden, wird jede Iterator-Kategorie durch die Operationen definiert, die auf sie angewendet werden können. Diese Definition bedeutet, dass jeder Typ, der die notwendigen Operationen unterstützt, als Iterator verwendet werden kann – beispielsweise unterstützt ein Zeiger alle für LegacyRandomAccessIterator erforderlichen Operationen, sodass ein Zeiger überall dort verwendet werden kann, wo ein LegacyRandomAccessIterator erwartet wird.

Alle Iterator-Kategorien (außer LegacyOutputIterator) können in einer Hierarchie organisiert werden, in der leistungsfähigere Iterator-Kategorien (z. B. LegacyRandomAccessIterator) die Operationen weniger leistungsfähiger Kategorien (z. B. LegacyInputIterator) unterstützen. Wenn ein Iterator in eine dieser Kategorien fällt und auch die Anforderungen von LegacyOutputIterator erfüllt, dann wird er als *mutable* Iterator bezeichnet und unterstützt *sowohl* Eingabe als auch Ausgabe. Nicht-mutable Iteratoren werden als *const* Iteratoren bezeichnet.

Iteratoren werden als *constexpr*-Iteratoren bezeichnet, wenn alle zur Erfüllung der Iterator-Kategorie-Anforderungen bereitgestellten Operationen constexpr-Funktionen sind.

(seit C++20)
Iterator-Kategorie Operationen und Speicheranforderung
     schreiben           lesen      Inkrement  dekrementieren     zufällig   
Zugriff
 zusammenhängend 
Speicher
ohne
   mehrere   
Durchgänge
mit
   mehrere   
Durchgänge
LegacyIterator Erforderlich
LegacyOutputIterator Erforderlich Erforderlich
LegacyInputIterator
(mutable, falls Schreiboperation unterstützt wird)
Erforderlich Erforderlich
LegacyForwardIterator
(erfüllt auch LegacyInputIterator)
Erforderlich Erforderlich Erforderlich
LegacyBidirectionalIterator
(erfüllt auch LegacyForwardIterator)
Erforderlich Erforderlich Erforderlich Erforderlich
LegacyRandomAccessIterator
(erfüllt auch LegacyBidirectionalIterator)
Erforderlich Erforderlich Erforderlich Erforderlich Erforderlich
   LegacyContiguousIterator[1]
(erfüllt auch LegacyRandomAccessIterator)
Erforderlich Erforderlich Erforderlich Erforderlich Erforderlich Erforderlich
  1. LegacyContiguousIterator Kategorie wurde erst formell in C++17 spezifiziert, aber die Iteratoren von std::vector, std::basic_string, std::array und std::valarray sowie Zeiger in C-Arrays werden in Code vor C++17 oft als eigene Kategorie behandelt.

Hinweis: Ein Typ, der die erforderlichen Operationen in einer Zeile der obigen Tabelle unterstützt, fällt nicht unbedingt in die entsprechende Kategorie. Eine vollständige Liste der Anforderungen finden Sie auf der Kategorie-Seite.

[bearbeiten] Definitionen

[bearbeiten] Typen und Schreibbarkeit

Ein Eingabeiterator i unterstützt den Ausdruck *i, der einen Wert eines beliebigen Objekttyps T ergibt, der als *Werttyp* des Iterators bezeichnet wird.

Ein Ausgabeiterator i hat eine nicht-leere Menge von Typen, die in den Iterator *geschrieben* werden können(bis C++20)indirectly_writable(seit C++20); für jeden solchen Typ T ist der Ausdruck *i = o gültig, wobei o ein Wert vom Typ T ist.

Für jeden Iteratortyp X, für den Gleichheit definiert ist(bis C++20), gibt es einen zugehörigen vorzeichenbehafteten Ganzzahltyp(bis C++20)ganzzahlähnlichen(seit C++20) Typ, der als *Differenztyp* des Iterators bezeichnet wird.

[bearbeiten] Dereferenzierbarkeit und Gültigkeit

So wie ein regulärer Zeiger auf ein Array garantiert, dass es einen Zeigerwert gibt, der hinter das letzte Element des Arrays zeigt, so gibt es auch für jeden Iteratortyp einen Iteratorwert, der hinter das letzte Element einer entsprechenden Sequenz zeigt. Ein solcher Wert wird als *Past-the-end*-Wert bezeichnet.

Werte eines Iterators i, für die der Ausdruck *i definiert ist, werden als *dereferenzierbar* bezeichnet. Die Standardbibliothek geht niemals davon aus, dass Past-the-end-Werte dereferenzierbar sind.

Iteratoren können auch *singuläre* Werte haben, die nicht mit einer Sequenz verbunden sind. Die Ergebnisse der meisten Ausdrücke sind für singuläre Werte undefiniert; die einzigen Ausnahmen sind

  • die Zuweisung eines nicht-singulären Wertes an einen Iterator, der einen singulären Wert enthält,
  • die Zerstörung eines Iterators, der einen singulären Wert enthält, und
  • für Iteratoren, die die Anforderungen von DefaultConstructible erfüllen, die Verwendung eines wertinitialisierten Iterators als Quelle einer Kopier-oder Verschiebungsoperation(seit C++11).

In diesen Fällen wird der singuläre Wert genauso überschrieben wie jeder andere Wert. Dereferenzierbare Werte sind immer nicht-singulär.

Ein *ungültiger* Iterator ist ein Iterator, der singulär sein kann.

[bearbeiten] Bereiche

Die meisten algorithmischen Templates der Standardbibliothek, die auf Datenstrukturen operieren, haben Schnittstellen, die Bereiche verwenden.

Ein Iterator j wird als von einem Iterator i *erreichbar* bezeichnet, wenn und nur wenn eine endliche Folge von Anwendungen des Ausdrucks ++i dazu führt, dass i == j. Wenn j von i erreichbar ist, beziehen sie sich auf Elemente derselben Sequenz.

Ein *Bereich* ist ein Paar von Iteratoren, die den Anfang und das Ende der Berechnung bezeichnen. Ein Bereich [ii) ist ein leerer Bereich; im Allgemeinen bezieht sich ein Bereich [ij) auf die Elemente in der Datenstruktur, beginnend mit dem Element, auf das i zeigt, bis zu, aber nicht einschließlich, dem Element, auf das j zeigt.

Der Bereich [ij) ist *gültig*, wenn und nur wenn j von i erreichbar ist.

(bis C++20)

Ein *Bereich* kann bezeichnet werden durch

  • [is), mit einem Iterator i und einem *Sentinel* s, die den Anfang und das Ende der Berechnung bezeichnen (i und s können unterschiedliche Typen haben), oder
  • i + [0n), mit einem Iterator i und einer Anzahl n, die den Anfang und die Anzahl der Elemente bezeichnen, auf die die Berechnung angewendet werden soll.
Iterator-Sentinel-Bereich

Ein Iterator und ein Sentinel, die einen Bereich bezeichnen, sind vergleichbar. [is) ist leer, wenn i == s; andernfalls bezeichnet [is) die Elemente in der Datenstruktur, beginnend mit dem Element, auf das i zeigt, bis zu, aber nicht einschließlich, dem Element, auf das der erste Iterator j zeigt, für das j == s gilt.

Ein Sentinel s wird von einem Iterator i als *erreichbar* bezeichnet, wenn und nur wenn eine endliche Folge von Anwendungen des Ausdrucks ++i dazu führt, dass i == s.

Wenn s von i erreichbar ist, bezeichnet [is) einen *gültigen* Bereich.

Gezählter Bereich

Ein *gezählter Bereich* i + [0n) ist leer, wenn n == 0; andernfalls bezeichnet i + [0n) die n Elemente in der Datenstruktur, beginnend mit dem Element, auf das i zeigt, bis zu, aber nicht einschließlich, dem Element, auf das das Ergebnis von n Anwendungen von ++i zeigt.

Ein gezählter Bereich i + [0n) ist *gültig*, wenn und nur wenn

  • n == 0; oder
  • alle folgenden Bedingungen erfüllt sind
    • n positiv ist,
    • i dereferenzierbar ist und
    • ++i + [0--n) gültig ist.
(seit C++20)

Das Ergebnis der Anwendung von Funktionen in der Standardbibliothek auf ungültige Bereiche ist undefiniert.

[bearbeiten] Iterator-Konzepte (seit C++20)

Ein neues System von Iteratoren, das auf Konzepten basiert, das sich von C++17-Iteratoren unterscheidet. Während die grundlegende Taxonomie ähnlich bleibt, unterscheiden sich die Anforderungen an die einzelnen Iterator-Kategorien leicht.

Definiert im Namespace std
spezifiziert, dass ein Typ durch Anwendung des Operators * indirekt lesbar ist
(Konzept) [bearbeiten]
spezifiziert, dass ein Wert in das von einem Iterator referenzierte Objekt geschrieben werden kann
(Konzept) [bearbeiten]
spezifiziert, dass ein semiregular-Typ mit Prä- und Post-Inkrementoperatoren inkrementiert werden kann
(Konzept) [bearbeiten]
spezifiziert, dass die Inkrementoperation auf einem weakly_incrementable-Typ *gleichheitserhaltend* ist und dass der Typ equality_comparable ist
(Konzept) [bearbeiten]
spezifiziert, dass ein Typ sich wie ein (vorzeichenbehafteter) Ganzzahltyp verhält
(exposition-only Konzept*)[bearbeiten]
spezifiziert, dass Objekte eines Typs inkrementiert und dereferenziert werden können
(Konzept) [bearbeiten]
spezifiziert, dass ein Typ ein Sentinel für einen input_or_output_iterator-Typ ist
(Konzept) [bearbeiten]
spezifiziert, dass der Operator - auf einen Iterator und ein Sentinel angewendet werden kann, um ihre Differenz in konstanter Zeit zu berechnen
(Konzept) [bearbeiten]
spezifiziert, dass ein Typ ein Eingabeiterator ist, d. h. seine referenzierten Werte können gelesen werden und er kann sowohl prä- als auch post-inkrementiert werden
(Konzept) [bearbeiten]
spezifiziert, dass ein Typ ein Ausgabeiterator für einen gegebenen Werttyp ist, d. h. Werte dieses Typs können hineingeschrieben werden und er kann sowohl prä- als auch post-inkrementiert werden
(Konzept) [bearbeiten]
spezifiziert, dass ein input_iterator ein Vorwärtsiterator ist, der Gleichheitsvergleich und Multi-Pass unterstützt
(Konzept) [bearbeiten]
spezifiziert, dass ein forward_iterator ein bidirektionaler Iterator ist, der die Rückwärtsbewegung unterstützt
(Konzept) [bearbeiten]
spezifiziert, dass ein bidirectional_iterator ein Zufallszugriff-Iterator ist, der die Vorwärtsbewegung in konstanter Zeit und Indizierung unterstützt
(Konzept) [bearbeiten]
spezifiziert, dass ein random_access_iterator ein zusammenhängender Iterator ist, der auf Speicherbereiche verweist, die im Speicher zusammenhängend sind
(Konzept) [bearbeiten]

[bearbeiten] Iterator-zugeordnete Typen (seit C++20)

Definiert im Namespace std
berechnet den Differenztyp eines weakly_incrementable-Typs
(Klassenschablone) [bearbeiten]
berechnet den Werttyp eines indirectly_readable-Typs
(Klassenschablone) [bearbeiten]
berechnet die zugehörigen Typen eines Iterators
(Alias-Schablone)[bearbeiten]

[bearbeiten] Iterator-Primitive

bietet eine einheitliche Schnittstelle zu den Eigenschaften eines Iterators
(Klassenschablone) [bearbeiten]
leere Klassentypen, die zur Angabe von Iterator-Kategorien verwendet werden
(Klasse) [bearbeiten]
(veraltet in C++17)
Basisklasse zur Vereinfachung der Definition der erforderlichen Typen für einfache Iteratoren
(Klassenschablone) [bearbeiten]

[bearbeiten] Iterator-Anpassungspunkte (seit C++20)

Definiert im Namespace std::ranges
(C++20)
wandelt das Ergebnis der Dereferenzierung eines Objekts in seinen zugehörigen rvalue-Referenztyp um
(Anpassungspunkt-Objekt)[bearbeiten]
(C++20)
tauscht die von zwei dereferenzierbaren Objekten referenzierten Werte
(Customization-Punkt-Objekt)[bearbeiten]

[bearbeiten] Konzept- und Hilfsoperatoren (seit C++20)

Eine Menge von Konzepten und zugehörigen Hilfsvorlagen, die dazu dienen, gängige Algorithmusoperationen einfacher einzuschränken.

Definiert in Header <iterator>
Definiert im Namespace std
Indirekte aufrufbare Konzepte
spezifiziert, dass ein aufrufbaren Typ mit dem Ergebnis der Dereferenzierung eines indirectly_readable Typs aufgerufen werden kann
(Konzept) [bearbeiten]
spezifiziert, dass ein aufrufbaren Typ, wenn er mit dem Ergebnis der Dereferenzierung eines indirectly_readable Typs aufgerufen wird, ein predicate erfüllt
(Konzept) [bearbeiten]
spezifiziert, dass ein aufrufbaren Typ, wenn er mit dem Ergebnis der Dereferenzierung zweier indirectly_readable Typen aufgerufen wird, ein predicate erfüllt
(Konzept) [bearbeiten]
spezifiziert, dass ein aufrufbaren Typ, wenn er mit dem Ergebnis der Dereferenzierung zweier indirectly_readable Typen aufgerufen wird, eine equivalence_relation erfüllt
(Konzept) [bearbeiten]
spezifiziert, dass ein aufrufbaren Typ, wenn er mit dem Ergebnis der Dereferenzierung zweier indirectly_readable Typen aufgerufen wird, eine strict_weak_order erfüllt
(Konzept) [bearbeiten]
Gemeinsame Algorithmus-Anforderungen
spezifiziert, dass Werte von einem indirectly_readable Typ zu einem indirectly_writable Typ verschoben werden können
(Konzept) [bearbeiten]
spezifiziert, dass Werte von einem indirectly_readable Typ zu einem indirectly_writable Typ verschoben werden können und dass das Verschieben über ein Zwischenobjekt erfolgen kann
(Konzept) [bearbeiten]
spezifiziert, dass Werte von einem indirectly_readable Typ zu einem indirectly_writable Typ kopiert werden können
(Konzept) [bearbeiten]
spezifiziert, dass Werte von einem indirectly_readable Typ zu einem indirectly_writable Typ kopiert werden können und dass das Kopieren über ein Zwischenobjekt erfolgen kann
(Konzept) [bearbeiten]
spezifiziert, dass die Werte, auf die zwei indirectly_readable Typen verweisen, vertauscht werden können
(Konzept) [bearbeiten]
spezifiziert, dass die Werte, auf die zwei indirectly_readable Typen verweisen, verglichen werden können
(Konzept) [bearbeiten]
spezifiziert die gemeinsamen Anforderungen für Algorithmen, die Elemente an Ort und Stelle neu ordnen
(Konzept) [bearbeiten]
(C++20)
spezifiziert die Anforderungen für Algorithmen, die sortierte Sequenzen durch Kopieren von Elementen zu einer Ausgabesequenz zusammenführen
(Konzept) [bearbeiten]
(C++20)
spezifiziert die gemeinsamen Anforderungen für Algorithmen, die Sequenzen zu sortierten Sequenzen permutieren
(Konzept) [bearbeiten]
Dienstprogramme
berechnet das Ergebnis des Aufrufs eines aufrufbaren Objekts auf das Ergebnis der Dereferenzierung einer Menge von indirectly_readable Typen
(Alias-Vorlage)[bearbeiten]
(C++20)
Hilfsvorlage zur Spezifizierung der Einschränkungen für Algorithmen, die Projektionen akzeptieren
(Klassenvorlage) [bearbeiten]
berechnet den Werttyp eines indirectly_readable Typs mittels Projektion
(Alias-Vorlage)[bearbeiten]

[bearbeiten] Iterator-Adapter

Iterator-Adapter für die Rückwärtsiteration
(Klassenvorlage) [bearbeiten]
erstellt einen std::reverse_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
Iterator-Adapter für die Einfügung am Ende eines Containers
(Klassenvorlage) [bearbeiten]
erstellt einen std::back_insert_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
Iterator-Adapter für die Einfügung am Anfang eines Containers
(Klassenvorlage) [bearbeiten]
erstellt einen std::front_insert_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
Iterator-Adapter für die Einfügung in einen Container
(Klassenvorlage) [bearbeiten]
erstellt einen std::insert_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
Iterator-Adapter, der einen Iterator in einen konstanten Iterator umwandelt
(Klassenvorlage) [bearbeiten]
berechnet einen konstanten Iteratortyp für einen gegebenen Typ
(Alias-Vorlage)[bearbeiten]
berechnet einen Sentinel-Typ zur Verwendung mit konstanten Iteratoren
(Alias-Vorlage)[bearbeiten]
erstellt einen std::const_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
erstellt einen std::const_sentinel vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
Iterator-Adapter, der zu einem rvalue dereferenziert
(Klassenvorlage) [bearbeiten]
Sentinel-Adapter für std::move_iterator
(Klassenvorlage) [bearbeiten]
erstellt einen std::move_iterator vom Typ, der aus dem Argument abgeleitet wird
(Funktionsvorlage) [bearbeiten]
passt einen Iteratortyp und dessen Sentinel an einen gemeinsamen Iteratortyp an
(Klassenvorlage) [bearbeiten]
Standard-Sentinel zur Verwendung mit Iteratoren, die die Grenze ihres Bereichs kennen
(Klasse) [bearbeiten]
Iterator-Adapter, der den Abstand zum Ende des Bereichs verfolgt
(Klassenvorlage) [bearbeiten]
Sentinel, der immer ungleich zu jedem weakly_incrementable Typ ist
(Klasse) [bearbeiten]

[bearbeiten] Stream-Iteratoren

Eingabe-Iterator, der aus std::basic_istream liest
(Klassenvorlage) [bearbeiten]
Ausgabe-Iterator, der in std::basic_ostream schreibt
(Klassenvorlage) [bearbeiten]
Eingabe-Iterator, der aus std::basic_streambuf liest
(Klassenvorlage) [bearbeiten]
Ausgabe-Iterator, der in std::basic_streambuf schreibt
(Klassenvorlage) [bearbeiten]

[bearbeiten] Iterator-Operationen

Definiert in Header <iterator>
bewegt einen Iterator um die angegebene Distanz vorwärts
(Funktionsvorlage) [bearbeiten]
gibt die Distanz zwischen zwei Iteratoren zurück
(Funktionsvorlage) [bearbeiten]
(C++11)
inkrementiert einen Iterator
(Funktionsvorlage) [bearbeiten]
(C++11)
dekrementiert einen Iterator
(Funktionsvorlage) [bearbeiten]
bewegt einen Iterator um die angegebene Distanz vorwärts oder zu einer gegebenen Grenze
(Algorithmus-Funktionsobjekt)[bearbeiten]
gibt die Distanz zwischen einem Iterator und einem Sentinel zurück oder die Distanz zwischen dem Anfang und dem Ende eines Bereichs
(Algorithmus-Funktionsobjekt)[bearbeiten]
inkrementiert einen Iterator um eine gegebene Distanz oder zu einer Grenze
(Algorithmus-Funktionsobjekt)[bearbeiten]
dekrementiert einen Iterator um eine gegebene Distanz oder zu einer Grenze
(Algorithmus-Funktionsobjekt)[bearbeiten]

[bearbeiten] Bereichszugriff (seit C++11)

Diese nicht-Member-Funktionsvorlagen bieten eine generische Schnittstelle für Container, einfache Arrays und std::initializer_list.

Definiert in der Header-Datei <array>
Definiert in Header <deque>
Definiert in Header <flat_map>
Definiert in Header <flat_set>
Definiert in Header <forward_list>
Definiert in Header <inplace_vector>
Definiert in Header <iterator>
Definiert in Header <list>
Definiert in Header <map>
Definiert in Header <regex>
Definiert in Header <set>
Definiert in Header <span>
Definiert in Header <string>
Definiert in Header <string_view>
Definiert in Header <unordered_map>
Definiert in Header <unordered_set>
Definiert in Header <vector>
Definiert im Namespace std
(C++11)(C++14)
gibt einen Iterator zum Anfang eines Containers oder Arrays zurück
(Funktionsvorlage) [bearbeiten]
(C++11)(C++14)
gibt einen Iterator zum Ende eines Containers oder Arrays zurück
(Funktionsvorlage) [bearbeiten]
gibt einen Reverse-Iterator zum Anfang eines Containers oder Arrays zurück
(function template) [bearbeiten]
(C++14)
gibt einen Reverse-End-Iterator für einen Container oder ein Array zurück
(function template) [bearbeiten]
(C++17)(C++20)
gibt die Größe eines Containers oder Arrays zurück
(Funktionsvorlage) [bearbeiten]
(C++17)
prüft, ob der Container leer ist
(function template) [bearbeiten]
(C++17)
erhält den Zeiger auf das zugrundeliegende Array
(function template) [bearbeiten]

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 1181 C++98 Array-Typen konnten keine Wertetypen sein sie können es
LWG 208 C++98 Iteratoren jenseits des Endes waren immer nicht-singulär sie können singulär sein
LWG 278 C++98 die Gültigkeit eines Iterators war nicht definiert als immer nicht-singulär definiert
LWG 324 C++98 Ausgabe-Iteratoren hatten Werttypen Ausgabe-Iteratoren haben stattdessen schreibbare Typen
LWG 407 C++98 singuläre Iteratoren konnten nicht zerstört werden erlaubt
LWG 408
(N3066)
C++98 singuläre Iteratoren konnten nicht kopiert werden erlaubt, wenn sie wertinitialisiert sind
LWG 1185
(N3066)
C++98 LegacyForwardIterator, LegacyBidirectionalIterator
und LegacyRandomAccessIterator
erfüllen immer LegacyOutputIterator
sie erfüllen möglicherweise nicht LegacyOutputIterator
LWG 1210
(N3066)
C++98 die Definition von Iterator-Singularität und
Erreichbarkeit hingen von Containern ab
hängen stattdessen von Sequenzen ab
LWG 3009 C++17 <string_view> stellte die
Bereichszugriffs-Funktionsvorlagen nicht bereit
stellt diese Vorlagen bereit
LWG 3987 C++23 <flat_map> und <flat_set> taten dies nicht
die Bereichszugriffs-Funktionsvorlagen bereitstellen
stellen diese Vorlagen bereit