Wenn ich das mache:
std::vector<int> hello;
Alles funktioniert super. Wenn ich es jedoch stattdessen zu einem Referenzvektor mache:
std::vector<int &> hello;
Ich bekomme schreckliche Fehler wie
Fehler C2528: 'Zeiger': Zeiger auf Referenz ist unzulässig
Ich möchte eine Reihe von Verweisen auf Strukturen in einen Vektor einfügen, damit ich mich nicht in Zeiger einmischen muss. Warum löst Vektor einen Wutanfall aus? Ist meine einzige Option, stattdessen einen Zeigervektor zu verwenden?
Antworten:
Der Komponententyp von Containern wie Vektoren muss zuweisbar sein . Referenzen können nicht zugewiesen werden (Sie können sie nur einmal initialisieren, wenn sie deklariert sind, und Sie können sie später nicht auf etwas anderes verweisen lassen). Andere nicht zuweisbare Typen sind ebenfalls nicht als Bestandteile von Containern
vector<const int>
zulässig , z . B. nicht zulässig.quelle
Ja, Sie können suchen
std::reference_wrapper
, dass dies eine Referenz imitiert, aber zuweisbar ist und auch "neu eingesetzt" werden kann.quelle
get()
ersten Aufruf zu umgehen, wenn Sie versuchen, auf eine Methode einer Instanz einer Klasse in diesem Wrapper zuzugreifen? ZBreference_wrapper<MyClass> my_ref(...); my_ref.get().doStuff();
ist nicht sehr referenzartig..get()
. Was Timdiels will, istoperator.
; Schauen Sie sich die neuesten Vorschläge / Diskussionen dazu an.Referenzen können naturgemäß nur zum Zeitpunkt ihrer Erstellung festgelegt werden. dh die folgenden zwei Zeilen haben sehr unterschiedliche Auswirkungen:
Weiter ist das illegal:
Wenn Sie jedoch einen Vektor erstellen, können Sie seinen Elementen bei der Erstellung keine Werte zuweisen. Sie machen im Wesentlichen nur eine ganze Reihe des letzten Beispiels.
quelle
Ion Todirel erwähnte bereits eine Antwort JA mit
std::reference_wrapper
. Seit C ++ 11 haben wir einen Mechanismus zum Abrufen von Objekten ausstd::vector
und Entfernen der Referenz mithilfe vonstd::remove_reference
. Im Folgenden finden Sie ein Beispiel, das mitg++
undclang
mit Option kompiliert-std=c++11
und erfolgreich ausgeführt wurde.quelle
std::remove_reference<>
hier nicht. Der Punkt vonstd::remove_reference<>
ist, Ihnen zu erlauben, "den Typ T zu schreiben, aber ohne eine Referenz zu sein, wenn es einer ist". Sostd::remove_reference<MyClass&>::type
ist es auch mit dem SchreibenMyClass
.for (MyClass obj3 : vec) std::cout << obj3.getval() << "\n";
(oderfor (const MyClass& obj3: vec)
wenn Siegetval()
const deklarieren , wie Sie sollten).boost::ptr_vector<int>
wird funktionieren.Bearbeiten: war ein zu verwendender Vorschlag
std::vector< boost::ref<int> >
, der nicht funktioniert, da Sie a nicht standardmäßig erstellen könnenboost::ref
.quelle
resize
. EnEs ist ein Fehler in der C ++ - Sprache. Sie können die Adresse einer Referenz nicht übernehmen, da dies dazu führen würde, dass auf die Adresse des Objekts verwiesen wird, und Sie daher niemals einen Zeiger auf eine Referenz erhalten können.
std::vector
arbeitet mit Zeigern auf seine Elemente, daher muss auf die gespeicherten Werte verwiesen werden können. Sie müssen stattdessen Zeiger verwenden.quelle
sizeof
Referenz nehmen.TL; DR
Verwenden Sie
std::reference_wrapper
wie folgt:Demo
Lange Antwort
Wie Standard schlägt vor , für einen Standard - Container,
X
Objekte des Typs enthaltenT
,T
müssenErasable
ausX
.Erasable
bedeutet, dass der folgende Ausdruck gut geformt ist:A
ist der Allokatortyp des Containers.m
ist eine Allokatorinstanz undp
ein Zeiger vom Typ*T
. Siehe hier für dieErasable
Definition.Standardmäßig
std::allocator<T>
wird als Vektor-Allokator verwendet. Mit dem Standardzuweiser entspricht die Anforderung der Gültigkeit vonp->~T()
(Beachten Sie, dass diesT
ein Referenztyp undp
ein Zeiger auf eine Referenz ist). Jedoch, Zeiger auf eine Referenz ist jedoch unzulässig , daher ist der Ausdruck nicht gut geformt.quelle
Wie andere bereits erwähnt haben, werden Sie wahrscheinlich stattdessen einen Zeigervektor verwenden.
Möglicherweise möchten Sie jedoch stattdessen einen ptr_vector verwenden!
quelle
Wie aus den anderen Kommentaren hervorgeht, können Sie nur Zeiger verwenden. Aber wenn es hilft, ist hier eine Technik, um zu vermeiden, direkt mit Zeigern zu konfrontieren.
Sie können Folgendes tun:
quelle
reinterpret_cast
wird nicht benötigt