2015-03-31 16 views
7

Das folgende kompiliert nicht (sehr ausführlichen Fehler, aber im Grunde "kann nicht überladen werden" und "ungültige Konvertierung von 'const void *' zu 'void *'"). Ich kann deshalb zum Beispiel push_back() kann nicht verstehen, kompilieren, da Sie nicht kopieren/verschieben in ein Foo* const, aber warum nicht diese Kompilierung:Vektor von const Zeigern?

#include <vector> 
using namespace std; 

class Foo; 

int main() 
{ 
    vector<Foo* const> vec; 
} 
+1

Vollständiger Fehler gefunden [hier] (http://ideone.com/EouxNT) –

+0

In C++ 03 Vektorelement musste CopyAssignable sein. In C++ 11 ist es immer noch nicht erlaubt, [siehe hier] (http://stackoverflow.com/questions/6954906/does-c11-allow-vectorconst-t). In der Tat würde ich vorschlagen, diese Frage zu duplizieren, wenn alle einverstanden sind. –

+0

Wie könnten Sie neue Elemente in den 'Vektor' einfügen? – Jagannath

Antwort

10

Der Vektor ist wahrscheinlich der einzige Behälter, die erfordert Elemente zu sein copy assignable. Dies liegt daran, dass die Elemente garantiert zusammenhängend im Speicher gespeichert sind. Wenn Sie also die Kapazität überschreiten, müssen Sie einen neuen Chunk zuweisen und Elemente neu zuweisen. Sie können dies nicht mit const Elementen tun.

Derselbe Fehler, wenn Sie versuchen, std::vector<const int>, oder in der Tat jede const Art.

+1

Warum benötigt die Neuzuweisung eine Zuweisung? Klingt eher nach Kopierfähigkeit ... –

+0

@KerrekSB: Aus der Sicht des Compilers ergeben sich die Zuordnung und Kopierbarkeit auf dasselbe. – datenwolf

+0

Kein Const-qualifizierter Typ; Es sollte funktionieren, wenn der Zuweisungsoperator const ist. – rightfold

1

Sie deklarieren einen Vektor, der const Zeiger von Foo enthält, das bedeutet, dass der Zeiger nicht geändert werden konnte. Wenn Sie ein Element in den Vektor einfügen, müssten Sie in eine const pointer schreiben (nicht gültig).

Sie sind sicher, es ist nicht: std::vector<Foo const *> vec; wo Foo nicht durch den Zeiger geändert werden könnte.

1

Das C/C++ const Schlüsselwort wird linksassoziativ, das heißt, sie das Token an seinen linken bewirkt, mit der Ausnahme, wenn const ist das erste Token in einer Erklärung. Also void *const bedeutet "Konstante (= unveränderlich) Zeiger auf void".

Daraus ergibt sich die Semantik sind:

int a; 
void * const ptr = (void*)&a; /* legal */ 

int b; 
ptr = (void*)&b; /* not permitted */ 

die später illegal ist, weil konstante Variablen bei Definition initialisiert werden muss und kann später nicht mehr geändert werden.

Wenn Sie std::vector<void * const> schreiben, bitten Sie den Compiler, die Vorlage als Vektor unveränderlicher Zeiger auf void zu instanziieren. Wie auch immer unveränderlich bedeutet, es kann nur bei der Definition zugewiesen werden, die jedoch nicht mit der dynamischen Natur von std::vector fliegt.

3

Vektorelemente müssen für viele Operationen zuweisbar sein: Wenn Sie ein Element in die Mitte des Vektors einfügen, müssen alle späteren Elemente neu zugewiesen werden. Const-qualifizierte Typen sind normalerweise nicht zuweisbar.

Wenn Sie keine Operationen ausführen, die eine Zuweisung erfordern, können Sie dennoch Vektoren nicht zuweisbarer Typen verwenden.

Sie können jedoch nur std::allocator<T> verwenden, wenn T ein nicht-konstanter Objekttyp ist, daher ist std::vector<const int> schlecht formatiert.

+0

Da C++ 11 Vektorelemente nicht zuweisbar sein müssen –

+0

@MattMcNabb: Absolut richtig, bearbeitet. –

+0

@MattMcNabb hmmmm, g ++ 4.9.2 und sogar gcc5 glaubt anders, aber ja, Sie sind richtig – vsoftco

Verwandte Themen