Zeiger auf ein Element aus std::map zurückgeben
-
Hallo zusammen,
wollte fragen, ob der folgende Code korrekt ist (der Compiler meckert schon mal nicht). Möchte einen Zeiger auf ein map-Element zurückgeben. Das Element selbst wiederum ist ein Vector von Zeigern auf andere Objekte.
const std::vector<FrameC *> *result = NULL; std::map<const int, std::vector<FrameC *> >::const_iterator resultIt = frameCollections.find(frameCollectionID); // nur wenn was gefunden wurde if (resultIt != frameCollections.end()) { result = &(resultIt->second); } return result;
Oder gebe ich hier ggf. nen Zeiger auf etwas zurück, dass am Ende der Methode out of scope geht?
Auch wundert mich, dass ich einem const std::vector<FrameC *> * nochmal einen Wert zuweisen kann....Vielen Dank schon einmal für eure Hilfe!
Ciao
-
@Reth sagte in Zeiger auf ein Element aus std::map zurückgeben:
Oder gebe ich hier ggf. nen Zeiger auf etwas zurück, dass am Ende der Methode out of scope geht?
Das brauchst du nicht zu befürchten, das worauf
resultIt
zeigt ist das echte Ding, der Vector in der Map. Und der Verweis darauf ist solange gültig, wie du nichts an der Map veränderst.Auch wundert mich, dass ich einem const std::vector<FrameC *> * nochmal einen Wert zuweisen kann....
Du hast es falsch rum verstanden. Du hast einen Zeiger auf eine Konstante deklariert, nicht einen konstanten Zeiger. Was eigentlich genau richtig klingt von der Logik her, daher bin ich verwundert, dass dich das selber wundert. Abgeschrieben?
-
@SeppJ
Super! Vielen Dank! Nein, nicht abgeschrieben nur immer noch elender Anfänger und das Ganze überall versucht zu lernen (aus Web, Büchern, Foren usw.). Hab quasi keine Erfahrung, noch weniger mit dem geconste usw. Hatte vergessen, dass wenn ich einen konstanten Zeiger zurückgeben wöllte, ein const vor den Zeiger-Stern muss, also: const std::vector<FrameC *> const *.
Heißt, so wie ich es jetzt habe, kann zwar der Zeiger verändert werden, nicht jedoch, dass worauf er zeigt - richtig?
-
@Reth sagte in Zeiger auf ein Element aus std::map zurückgeben:
const std::vector<FrameC *> const *
das ist genau dasselbe wie
@Reth sagte in Zeiger auf ein Element aus std::map zurückgeben:
const std::vector<FrameC *> * // ...
Merk' es dir vielleicht so:
[Typ auf den der Zeiger Zeigt] * [Qualifier des Zeigers] [Name]
:int const * const foo;
und lies von hinten nach vorne:
foo
ist einconst
pointer toconst int
.int * const bar;
bar
ist einconst
pointer toint
.int const * qux;
qux
ist ein pointer toconst int
.nebenbei:
const const const int const const foo
ist dasselbe wieconst int foo
oderint const foo
.
-
Außer dass doppelte cv-Qualifizierer nicht erlaubt sind?
-
@Swordfish
Stimmt, das hatte ich durcheinander gebracht bzw. wieder vergessen (hatte die Schreib- und Leseweisen vor vielen Jahren schon mal angeschaut gehabt, aber in der Zwischenzeit nichts mehr mit C++ gemacht).Aber nochmal zurück zu meiner anderen Frage:
Heißt, so wie ich es jetzt habe (siehe Eingangspost), kann zwar der Zeiger verändert werden, nicht jedoch, dass worauf er zeigt - richtig?
-
@SeppJ sagte in Zeiger auf ein Element aus std::map zurückgeben:
Außer dass doppelte cv-Qualifizierer nicht erlaubt sind?
Aja, die Ausnahme war ja
long
. ([dcl.spec]/2)@Reth sagte in Zeiger auf ein Element aus std::map zurückgeben:
Heißt, so wie ich es jetzt habe (siehe Eingangspost), kann zwar der Zeiger verändert werden, nicht jedoch, dass worauf er zeigt - richtig?
Ja.
-
Besten Dank!
-
Desweiteren kannst du dir mal Gedanken machen, ob die ganzen Zeiger wirklich nötig sind. Grundsätzlich sollte man zuerst versuchen nur mit den Objekten selbst, bzw. Referenzen auf die Objekte, zu arbeiten.
Wenn das wirklich nicht geht, dann sollte man über Smart-Pointer ( std::unique_ptr<T>, std::shared_ptr<T> ) nachdenken.Das nur als Hinweis, wenn du den nächsten Lern-Schritt gehen willst
-
Ich kenne den Zusammenhang nicht, würde aber auch eher dazu tendieren den Iterator statt dem Pointer zurückzugeben. Es geht sonst relativ unnötig Information verloren, z.B. Die Map sollte z.b. Debugfunktionen haben um zu testen das der Iterator zur Map gehört. Würde auch eher zu keinen Pointern im Vector raten vermute aber das hat mit Vererbung zu tun.
-
@TGGC sagte in Zeiger auf ein Element aus std::map zurückgeben:
Würde auch eher zu keinen Pointern im Vector raten vermute aber das hat mit Vererbung zu tun.
Wahrscheinlich ja. Wobei da direkt auffällt, dass das so aussieht, als wären hier die Besitzverhältnisse nicht geklärt. Weder wird hier ein Pointertyp verwendet, der die Besitzverhältnisse ausdrückt; noch ist ein roher Vector ein Typ, der Besitz auf indirekt verwiesene Ressourcen anmeldet. Daher wäre es schon interessant zu erfahren, was da genau dahinter steckt, denn höchstwahrscheinlich liegt hier ein Fehler vor. Der Threadersteller macht sich ja grundsätzlich Gedanken um Gültigkeit von Verweisen, daher wäre jetzt eine gute Gelegenheit, ihm die saubere Modellierung von Besitzverhältnissen beizubringen.
-
@Swordfish sagte in Zeiger auf ein Element aus std::map zurückgeben:
@SeppJ sagte in Zeiger auf ein Element aus std::map zurückgeben:
Außer dass doppelte cv-Qualifizierer nicht erlaubt sind?
Aja, die Ausnahme war ja
long
. ([dcl.spec]/2)Ähh,
long
mag zwar doppelt vorkommen dürfen, aber auch nur, weil es dann eine andere Bedeutung hat.
-
error: 'long long long' is too long for GCC
-
@wob sagte in Zeiger auf ein Element aus std::map zurückgeben:
error: 'long long long' is too long for GCC
Ja,long long long
ist falsch, korrekt wärelong long li long
.
https://www.youtube.com/watch?v=uc2UEfWjvo8
-
long int long i; // 100% korrektes C++
Ahhh!
PS:
const long typedef int volatile long i; // Auch 100% korrekt
Vielleicht ist C++ doch nicht so schön wie gedacht.
-
int volatile long static unsigned const long i = 42;
-
Ich raffs nicht. Wieso nicht einfach so was:
#include <iostream> #include <vector> #include <map> struct A { uint32_t id; uint32_t irgendwas_anderes; }; std::map<uint32_t, std::vector<A>> my_map; const std::vector<A> get_id(const uint32_t id) { std::map<uint32_t, std::vector<A>>::iterator iter = my_map.find(id); if (iter != my_map.end()) { return iter->second; } return {}; } int main() { my_map[1] = std::vector<A>{{8, 1111}}; my_map[2] = std::vector<A>{{4, 111}, {8, 1111}}; my_map[3] = std::vector<A>{{2, 11}, {4, 111}, {8, 1111}}; my_map[4] = std::vector<A>{{1, 1}, {2, 11}, {4, 111}, {8, 1111}}; std::cout << get_id(0).size() << std::endl; std::cout << get_id(4)[3].irgendwas_anderes << std::endl; std::cout << get_id(5).size() << std::endl; }
-
Dieser Beitrag wurde gelöscht!
-
@EinNutzer0 sagte in Zeiger auf ein Element aus std::map zurückgeben:
const std::vector<A> get_id(const uint32_t id)
Jedesmal eine Vectorkopie ausliefern?
-
@manni66 sagte in Zeiger auf ein Element aus std::map zurückgeben:
@EinNutzer0 sagte in Zeiger auf ein Element aus std::map zurückgeben:
const std::vector<A> get_id(const uint32_t id)
Jedesmal eine Vectorkopie ausliefern?
Stimmt, danke... also doch einen Zeiger zurückgeben.