Namensräume
Varianten
Aktionen

C++ benannte Anforderungen: SequenceContainer

Von cppreference.com
 
 
C++ benannte Anforderungen
 

Ein SequenceContainer ist ein Container, der Objekte desselben Typs in einer linearen Anordnung speichert.

Inhalt

[bearbeiten] Anforderungen

Gegeben seien folgende Typen und Werte

Typ Definition
C eine Sequenzcontainer-Klasse
T der Elementtyp von C
A der Allokator-Typ von C
R (seit C++23) ein Typ, der container-compatible-range <T> modelliert
Args (seit C++11) ein Template-Parameterpaket
Iter C::iterator
Ref C::reference
CRef C::const_reference
Wert Definition
v ein Wert vom Typ C
cv ein Wert vom Typ const C
i, j LegacyInputIteratoren, so dass [ij) ein gültiger Bereich ist und die Iteratoren auf Elemente verweisen, die implizit in C::value_type konvertierbar sind
rg (seit C++23) ein Wert vom Typ R
il (seit C++11) ein Wert vom Typ std::initializer_list<C::value_type>
n ein Wert vom Typ C::size_type
p ein gültiger const Iterator in v
q ein gültiger dereferenzierbarer const Iterator in v
q1, q2 const Iteratoren in v, so dass [q1q2) ein gültiger Bereich ist
t ein Wert(bis C++11)ein lvalue oder const rvalue(seit C++11) vom Typ C::value_type
rv (seit C++11) ein nicht-const rvalue vom Typ C::value_type
args (seit C++11) ein Funktionsparameterpaket mit dem Muster Arg&&

C erfüllt die Anforderungen von SequenceContainer, wenn alle folgenden Bedingungen erfüllt sind

  • C erfüllt die Anforderungen von Container.
  • Die folgenden Anweisungen und Ausdrücke sind wohlgeformt und haben die spezifizierte Semantik
Grundlegende Operationen
(erforderlich für alle Sequenzcontainer in der Standardbibliothek außer std::array(seit C++11))
Anweisung     Semantik[1]
C c(n, t); Auswirkung Konstruiert den Sequenzcontainer, der n Kopien von t enthält.
Vorbedingung

T ist CopyInsertable in C.

(seit C++11)
Nachbedingung  std::distance(c.begin(), c.end()) ist n.
C c(i, j); Auswirkung Konstruiert den Sequenzcontainer, der elementweise gleich dem Bereich [ij) ist.
  • Jeder Iterator im Bereich [ij) wird genau einmal dereferenziert.
Vorbedingung

T ist EmplaceConstructible in C aus *i.

(seit C++11)
Nachbedingung std::distance(c.begin(), c.end()) ist std::distance(i, j).
Ausdruck  Typ  Semantik
C(std::from_range, rg)
(seit C++23)
C Auswirkung Konstruiert den Sequenzcontainer, der elementweise gleich dem Bereich rg ist.
  • Jeder Iterator im Bereich rg wird genau einmal dereferenziert.
Vorbedingung T ist EmplaceConstructible in C aus *ranges::begin(rg).
Nachbedingung std::distance(begin(), end()) ist ranges::distance(rg).
C(il)
(seit C++11)
C Entspricht C(il.begin(), il.end()).
v = il
(seit C++11)
C& Auswirkung Weist den von il repräsentierten Bereich v zu.[2]
Rückgabewert *this
Vorbedingung T ist CopyInsertable in C und CopyAssignable.
Nachbedingung Bestehende Elemente von v werden entweder zerstört oder zugewiesen.
v.emplace(p, args)
(seit C++11)
Iter  Auswirkung Fügt ein Objekt vom Typ T, konstruiert mit std::forward<Args>(args)..., vor p ein.
Rückgabewert Ein Iterator, der auf das neue Element zeigt, das aus args in v konstruiert wurde.
Vorbedingung T ist EmplaceConstructible in C aus args.
v.insert(p, t) Iter Auswirkung Fügt eine Kopie von t vor p ein.
Rückgabewert Ein Iterator, der auf die Kopie von t zeigt, die in v eingefügt wurde.
Vorbedingung

T ist CopyInsertable in C.

(seit C++11)
v.insert(p, rv)
(seit C++11)
Iter Auswirkung Fügt eine Kopie von rv vor p ein, möglicherweise unter Verwendung von Move-Semantik.
Rückgabewert Ein Iterator, der auf die Kopie von rv zeigt, die in v eingefügt wurde.
Vorbedingung T ist MoveInsertable in C.
v.insert(p, n, t) Iter Auswirkung Fügt n Kopien von t vor p ein.
Rückgabewert Ein Iterator, der auf die Kopie des ersten in v eingefügten Elements zeigt, oder p, wenn n 0 ist.
Vorbedingung

T ist CopyInsertable in C und CopyAssignable.

(seit C++11)
v.insert(p, i, j) Iter Auswirkung Fügt Kopien von Elementen im Bereich [ij) vor p ein.
  • Jeder Iterator im Bereich [ij) wird genau einmal dereferenziert.
Rückgabewert Ein Iterator, der auf die Kopie des ersten in v eingefügten Elements zeigt, oder p, wenn i == j true ist.
Vorbedingung
(seit C++11)
  • i und j befinden sich nicht in v.
v.insert_range(p, rg)
(seit C++23)
Iter Auswirkung Fügt Kopien von Elementen in rg vor p ein.
  • Jeder Iterator im Bereich rg wird genau einmal dereferenziert.
Rückgabewert Ein Iterator, der auf die Kopie des ersten in v eingefügten Elements zeigt, oder p, wenn rg leer ist.
Vorbedingung
v.insert(p, il)
(seit C++11)
Iter Entspricht v.insert(p, il.begin(), il.end()).
v.erase(q) Iter Auswirkung Löscht das von q referenzierte Element.
Rückgabewert Ein Iterator, der auf das Element zeigt, das unmittelbar auf q folgt, bevor das Element gelöscht wird, oder v.end(), wenn kein solches Element existiert.
v.erase(q1, q2) Iter Auswirkung Löscht Elemente im Bereich [q1q2).
Rückgabewert Ein Iterator, der auf das Element zeigt, auf das q2 vor dem Löschen von Elementen gezeigt hat, oder v.end(), wenn kein solches Element existiert.
v.clear() void Auswirkung Zerstört alle Elemente in v.
  • Macht alle Referenzen, Zeiger und Iteratoren ungültig, die sich auf Elemente von v beziehen, und kann den Past-the-End-Iterator ungültig machen.
Nachbedingung v.empty() ist true.
Komplexität Linear.
v.assign(i, j) void Auswirkung Ersetzt Elemente in v durch eine Kopie von [ij).
  • Macht alle Referenzen, Zeiger und Iteratoren ungültig, die sich auf Elemente von v beziehen.
  • Jeder Iterator in [ij) wird genau einmal dereferenziert.
Vorbedingung
(seit C++11)
  • i und j befinden sich nicht in v.
v.assign_range(rg)
(seit C++23)
void Auswirkung Ersetzt Elemente in v durch eine Kopie jedes Elements in rg.
  • Wenn std::assignable_from
        <T&, ranges::range_reference_t<R>>
    nicht modelliert wird, ist das Programm ill-formed.
  • Macht alle Referenzen, Zeiger und Iteratoren ungültig, die sich auf Elemente von v beziehen.
  • Jeder Iterator im Bereich rg wird genau einmal dereferenziert.
Vorbedingung
v.assign(il)
(seit C++11)
void Entspricht v.assign(il.begin(), il.end()).
v.assign(n, t) void Auswirkung Ersetzt Elemente in v durch n Kopien von t.
Vorbedingung

T ist CopyInsertable in C und CopyAssignable.

(seit C++11)
    Zusätzliche Operationen[3]
(nur für angegebene Sequenzcontainer erforderlich, ohne std::)
Ausdruck  Typ  Semantik
v.front() Ref Container basic_string, array, vector, inplace_vector, deque, list, forward_list
Rückgabewert *v.begin()
cv.front() CRef Container basic_string, array, vector, inplace_vector, deque, list, forward_list
Rückgabewert *cv.begin()
v.back() Ref Container basic_string, array, vector, inplace_vector, deque, list
Entspricht auto tmp = v.end(); --tmp; return *tmp;[4].
cv.back() CRef Container basic_string, array, vector, inplace_vector, deque, list
Entspricht auto tmp = cv.end(); --tmp; return *tmp;[5].
v.emplace_front(args)
(seit C++11)
void Container deque, list, forward_list
Auswirkung Setzt ein Objekt vom Typ T, konstruiert mit std::forward<Args>(args)..., am Anfang ein.
Rückgabewert v.front()
Vorbedingung T ist EmplaceConstructible in C aus args.
v.emplace_back(args)
(seit C++11)
void Container vector, inplace_vector, deque, list
Auswirkung Hängt ein Objekt vom Typ T an, konstruiert mit std::forward<Args>(args)....
Rückgabewert v.back()
Vorbedingung T ist EmplaceConstructible in C aus args.
v.push_front(t) void Container deque, list, forward_list
Auswirkung Fügt eine Kopie von t am Anfang ein.
Vorbedingung

T ist CopyInsertable in C.

(seit C++11)
v.push_front(rv)
(seit C++11)
void Container deque, list, forward_list
Auswirkung Fügt eine Kopie von rv am Anfang ein, möglicherweise unter Verwendung von Move-Semantik.
Vorbedingung T ist MoveInsertable in C.
v.prepend_range(rg)
(seit C++23)
void Container deque, list, forward_list
Auswirkung Fügt[6] Kopien von Elementen in rg vor v.begin() ein.
  • Jeder Iterator im Bereich rg wird genau einmal dereferenziert.
Vorbedingung T ist EmplaceConstructible in C aus *ranges::begin(rg).
v.push_back(t) void Container basic_string, vector, inplace_vector, deque, list
Auswirkung Hängt eine Kopie von t an.
Vorbedingung

T ist CopyInsertable in C.

(seit C++11)
v.push_back(rv)
(seit C++11)
void Container basic_string, vector, inplace_vector, deque, list
Auswirkung Hängt eine Kopie von rv an, möglicherweise unter Verwendung von Move-Semantik.
Vorbedingung T ist MoveInsertable in C.
v.append_range(rg)
(seit C++23)
void Container vector, inplace_vector, deque, list
Auswirkung Fügt[6] Kopien von Elementen in rg vor v.end() ein.
  • Jeder Iterator im Bereich rg wird genau einmal dereferenziert.
Vorbedingung T ist EmplaceConstructible in C aus *ranges::begin(rg).
v.pop_front() void Container deque, list, forward_list
Auswirkung Zerstört das erste Element.
Vorbedingung a.empty() ist false.
v.pop_back() void Container basic_string, vector, inplace_vector, deque, list
Auswirkung Zerstört das letzte Element.
Vorbedingung a.empty() ist false.
v[n] Ref Container basic_string, array, vector, inplace_vector, deque
Entspricht return *(v.begin() + n);.
cv[n] CRef Container basic_string, array, vector, inplace_vector, deque
Entspricht return *(cv.begin() + n);.
v.at(n) Ref Container basic_string, array, vector, inplace_vector, deque
Rückgabewert *(v.begin() + n)
Ausnahmen Wirft std::out_of_range, wenn n >= v.size() true ist.
cv.at(n) CRef Container basic_string, array, vector, inplace_vector, deque
Rückgabewert *(cv.begin() + n)
Ausnahmen Wirft std::out_of_range, wenn n >= cv.size() true ist.
Anmerkungen
  1. Für einen Ausdruck, dessen Wirkung äquivalent zu einigen anderen Operationen ist, werden die Bedingungen der Ausdrücke innerhalb dieser Operationen über die in der Tabelle aufgeführten Bedingungen hinaus übernommen.
  2. std::array unterstützt die Zuweisung von einer Klammer-initialisierten Initialisierungsliste, aber nicht von einer std::initializer_list.
  3. Alle nachfolgenden Operationen außer prepend_range und append_range(seit C++23) benötigen amortisiert konstante Zeit.
  4. In C++98 wurde tmp mit dem Typ C::iterator deklariert.
  5. In C++98 wurde tmp mit dem Typ C::const_iterator deklariert.
  6. 6.0 6.1 Die Einfügereihenfolge relativ zur Reihenfolge der Elemente in rg ist nicht umkehrend.

Zusätzlich gilt für jeden Sequenzcontainer

  • Ein Konstruktor-Template, das zwei Input-Iteratoren annimmt, und die Member-Funktions-Templates von insert, append, assign, replace, die zwei Input-Iteratoren annehmen, nehmen nicht an der Überladungsauflösung teil, wenn das entsprechende Template-Argument nicht LegacyInputIterator erfüllt.
  • Eine Deduktionsanleitung, die entweder einen LegacyInputIterator oder einen Allocator-Template-Parameter hat, nimmt nicht an der Überladungsauflösung teil, wenn der Typ, der sich nicht als Input-Iterator bzw. Allokator qualifiziert, für diesen Parameter deduziert wird.
(seit C++17)

[bearbeiten] Standardbibliothek

Die folgenden Standardbibliotheks-String-Typen und Container erfüllen die Anforderungen von SequenceContainer

speichert und manipuliert Zeichenfolgen
(Klassenvorlage) [edit]
(C++11)
fest dimensioniertes, inplace, zusammenhängendes Array
(Klassenvorlage) [edit]
reservierbares, zusammenhängendes Array
(Klassenvorlage) [edit]
reservierbares, festes Kapazitäts-Array, Inplace, zusammenhängend
(Klassenvorlage) [edit]
Doppelt-endende Warteschlange
(Klassenvorlage) [edit]
Einfach verkettete Liste
(Klassenvorlage) [edit]
Doppelt verkettete Liste
(Klassenvorlage) [edit]

[bearbeiten] Hinweise zur Verwendung

Container Vorteile Nachteile
std::vector Schneller Zugriff, zusammenhängender Speicher Größtenteils ineffiziente Einfügungen/Löschungen
std::inplace_vector Schneller Zugriff, inplace zusammenhängender Speicher Feste Kapazität und größtenteils ineffiziente Einfügungen/Löschungen
std::array Schneller Zugriff, inplace zusammenhängender Speicher Feste Anzahl von Elementen und keine Einfügung/Löschung
std::deque Schneller Zugriff, effiziente Einfügung/Löschung am Anfang/Ende Ineffiziente Einfügung/Löschung in der Mitte der Sequenz
std::list
std::forward_list
Effiziente Einfügung/Löschung in der Mitte der Sequenz Zugriff ist meistens lineare Zeit

[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
LWG 139 C++98 die optionalen Operationen sollten nicht für die bezeichneten Container implementiert sein
als mit amortisierter Zeit erforderlich
erforderlich mit amortisierter Zeit
LWG 149 C++98 v.insert(p, t) gab Iter zurück, während
v.insert(p, n, t) und v.insert(p, n, t) void zurückgaben
sie alle Iter zurückgeben
LWG 151 C++98 q1 musste dereferenzierbar sein[1] er kann nicht dereferenzierbar sein
LWG 355 C++98 das Aufrufen von v.back() oder v.pop_back() würde
--v.end() ausführen, was gefährlich ist[2]
dekrementiert eine Kopie
von v.end() stattdessen
LWG 589 C++98 die Elemente, auf die i und j verweisen
könnten nicht in C::value_type konvertierbar sein
sie sind implizit
konvertierbar in C::value_type
LWG 2194 C++11 std::queue, std::priority_queue und
std::stack waren auch SequenceContainer[3]
sie sind keine SequenceContainer
LWG 2231 C++11 die Anforderung an die Komplexität von v.clear()
wurde in C++11 versehentlich weggelassen
Komplexität als linear bestätigt
LWG 3927 C++98 operator[] hatte keine implizite Anforderung die implizite Anforderung hinzugefügt
  1. Es handelt sich um einen Fehler, da er dazu führt, dass das Verhalten von v.erase(v.begin(), v.end()) undefiniert ist, wenn v ein leerer Container ist.
  2. Wenn der Typ von v.end() ein fundamentaler Typ ist, ist --v.end() ill-formed. Es ist gefährlich, wenn der Typ von v ein Template ist, in diesem Fall kann dieser Fehler schwer zu finden sein.
  3. Sie wurden in C++98 nicht als SequenceContainer dokumentiert.