Die Containeranforderungen wurden von C ++ 03 auf C ++ 11 geändert. Während C ++ 03 pauschale Anforderungen hatte (z. B. Kopierkonstruierbarkeit und Zuweisbarkeit für Vektoren), definiert C ++ 11 feinkörnige Anforderungen für jede Containeroperation (Abschnitt 23.2).
Infolgedessen können Sie beispielsweise einen Typ, der kopierkonstruierbar, aber nicht zuweisbar ist, wie z. B. eine Struktur mit einem const-Element, in einem Vektor speichern, solange Sie nur bestimmte Operationen ausführen, für die keine Zuweisung erforderlich ist (Konstruktion und push_back
solche Operationen) ; insert
nicht ist).
Was ich mich frage ist: Bedeutet das, dass der Standard jetzt erlaubt vector<const T>
? Ich sehe keinen Grund, warum dies nicht der Fall sein sollte - const T
genau wie eine Struktur mit einem const-Member ist ein Typ, der kopierkonstruierbar, aber nicht zuweisbar ist -, aber ich habe möglicherweise etwas übersehen.
(Ein Teil von dem, was mich denken lässt, dass ich etwas verpasst habe, ist, dass der gcc-Trunk abstürzt und brennt, wenn Sie versuchen zu instanziieren vector<const T>
, aber es ist in Ordnung, vector<T>
wenn T ein const-Mitglied hat).
address
Elementfunktionen im Standardzuweiser: Wenn T const ist, haben diese beiden Überladungen dieselbe Signatur. Eine einfache Möglichkeit, dies zu korrigieren, besteht darinstd::allocator<const T>
, eine der Überlastungen zu spezialisieren und zu entfernen.push_back
. Aber wenn es nicht beabsichtigt ist, ist es besser, wenn wir es nicht tun. Ich war nur neugierig.std::vector<const T>
genau verwendet, weil es sehr ähnlich istconst std::vector<T>
, aber ohne die negativen Auswirkungen des letzteren auf die Klasse, die es hält. In der Tatstd::vector<const T>
ist genau das, was ich semantisch in den meisten Fällen brauche, wo ich benutzevector
. Jetzt muss ich fallenconst
- zusammen mit der Zuverlässigkeit, die es bietet.Aktualisieren
Unter der akzeptierten (und richtigen) Antwort habe ich 2011 kommentiert:
Mit dem bevorstehenden C ++ 17-Entwurf scheint es mir, dass wir jetzt legalisiert haben
vector<const T>
, und ich glaube auch, dass wir es versehentlich getan haben . :-)P0174R0 entfernt die
address
Überlastungen vonstd::allocator<T>
. P0174R0 erwähnt die Unterstützung nichtstd::allocator<const T>
als Teil seiner Begründung.Korrektur
In den Kommentaren unten stellt TC korrekt fest, dass die
address
Überladungen veraltet und nicht entfernt sind. Mein Fehler. Die veralteten Mitglieder erscheinen nicht in 20.10.9, wo dasstd::allocator
definiert ist, sondern werden stattdessen in Abschnitt D.9 verbannt. Ich habe es versäumt, Kapitel D nach dieser Möglichkeit zu durchsuchen, als ich dies gepostet habe.Danke TC für die Korrektur. Ich habe darüber nachgedacht, diese irreführende Antwort zu löschen, aber vielleicht ist es am besten, sie mit dieser Korrektur zu belassen, damit möglicherweise jemand anderes die Spezifikation nicht so falsch liest, wie ich es getan habe.
quelle
address
.vector<const T>
:)Obwohl wir bereits sehr gute Antworten darauf haben, habe ich beschlossen, mit einer praktischeren Antwort beizutragen, um zu zeigen, was getan werden kann und was nicht.
Das funktioniert also nicht:
vector<const T> vec;
Lesen Sie einfach die anderen Antworten, um zu verstehen, warum. Und wie Sie vielleicht vermutet haben, funktioniert dies auch nicht:
vector<const shared_ptr<T>> vec;
T
ist nicht mehrconst
, sondernvector
hältshared_ptr
s, nichtT
s.Auf der anderen Seite, dies tut Arbeit:
vector<const T *> vec; vector<T const *> vec; // the same as above
In diesem Fall ist const jedoch das Objekt, auf das gezeigt wird, nicht der Zeiger selbst (was der Vektor speichert). Dies wäre gleichbedeutend mit:
vector<shared_ptr<const T>> vec;
Welches ist in Ordnung.
Wenn wir jedoch
const
das Ende des Ausdrucks einfügen, wird der Zeiger jetzt in a umgewandeltconst
, sodass Folgendes nicht kompiliert wird:vector<T * const> vec;
Ein bisschen verwirrend, stimme ich zu, aber man gewöhnt sich daran.
quelle
Ergänzend zu den anderen Antworten besteht ein anderer Ansatz darin, Folgendes zu verwenden:
vector<unique_ptr<const T>> vec;
Wenn Sie dies durchsetzen möchten, hat dies nur
vec
das Eigentum an den Elementen. Oder wenn Sie eine Dynamik zum Verschiebenvec
und Verschieben von Objekten wünschen .Wie erwähnt, Zeiger
const
kann Semantik verwirrend, abershared_ptr
undunique_ptr
ist es nicht.const unique_ptr<T>
ist ein const-Zeiger undunique_ptr<const T>
ein const-Zeiger, wie Sie es erwarten würden.quelle