Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

02.01.2016, 11:12

C++ <map> Was passiert, wenn ein Key nicht vorhanden ist?

Hallo Forum,

was passiert, wenn ein Key von std::map<int, std::list<sf::Vector2f> > nicht vorhanden ist, man allerdings durch die Liste iteriert?

Als konkretes Beispiel:

Ich verwende die nachfolgende Map zur Einteilung der Karte eines Strategiespiels in eine Vielzahl kleiner Rauten (mit dem Key int). Die Koordinaten der sich in einer Raute befindenden Einheiten werden in einer Liste gespeichert (std::list<sf::Vector2f>):

C-/C++-Quelltext

1
std::map<int, std::list<sf::Vector2f> > mMapEinheitenKoordinaten;


Bei der Kollisionsabfrage werden dann nur die Einheiten, die sich auf der entsprechenden Raute + die umliegenden 8 Rauten betrachtet, dadurch spare ich mir eine Vielzahl von Abfragen. Ich iteriere also durch die Liste von Koordinaten mit entsprechendem Key von begin() bis end().

Oft kommt es allerdings vor, dass eine Raute keine Einheiten beinhaltet, der entsprechende Key existiert dann bei mir im Programm auch nicht. Kann die folgende Code-Zeile dann irgendwelche Probleme machen?

C-/C++-Quelltext

1
for(std::list<sf::Vector2f>::iterator it = mMapEinheitenKoordinaten[Key].begin(); it != mMapEinheitenKoordinaten[Key].end(); it ++){...}


Ich möchte nämlich eigentlich nicht jedes mal mittels find() überprüfen lassen, ob der Key vorhanden ist, wenn dies nicht notwendig ist :)
Bis jetzt macht es keine Probleme... aber wer weiß ob das immer so ist? ?(

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

02.01.2016, 11:18

Solche Fragen kannst du dir in der Referenz nachschauen:
http://www.cplusplus.com/reference/map/map/operator[]/

Zitat

If k matches the key of an element in the container, the function returns a reference to its mapped value.

If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

A similar member function, map::at, has the same behavior when an element with the key exists, but throws an exception when it does not.


Falls du da etwas nicht verstehst oder unklar ist, einfach melden. :)

3

02.01.2016, 11:28

Es wird eine neue, leere liste erstellt durch die du dann iterierst. Btw würde ich nur in seltenen fällen auf std::list setzen, eher auf vector.

4

02.01.2016, 11:34

drakon vielen Dank für die Seite, habe ich genauso verstanden wie Roflo es gerade geschrieben hat, es wird also jedes mal eine neue leere Liste erstellt, wenn keine Liste zu dem Key existiert. Also kann ich gleich je Raute eine leere Liste erstellen und brauche die Keys nicht zu löschen.

@Roflo: Danke für den Hinweis, allerdings sind nur maximal 4-5 Einheiten auf einer Raute, dadurch ist die Liste sehr kurz. Ich denke, dass sich Vector und Liste da nichts nehmen.

5

02.01.2016, 11:52

Vielleicht bietet sich auch eine Klasse Raute an, in der neben den einheiten (kann man auch eine Klasse Einheit machen) bestimmt noch andere Dinge sind.

6

02.01.2016, 12:25

Die Einheiten haben ihre eigene Klasse mit entsprechenden Methoden. Für die Verwaltung der Kollisionsabfragen werden nur die Positionen der Einheiten im "Einheiten-Manager" zwischen den einzelnen Einheiten ausgetauscht. So kann ich jeder Einheit einen bestimmten Wahrnehmungsradius geben.

Meine Einheiten sind sozusagen eigenständige "Software-Agenten", die auf Dinge innerhalb ihres Wahrnehmungsradius eigenständig reagieren. Ich habe keine zentrale Verwaltung, lediglich ein Informationsaustausch findet über den übergeordneten "Einheiten-Manager" statt (Position, Richtungsvektor, Geschwindigkeit).

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

02.01.2016, 14:47

Wofür genau sind diese Keys? Sollte eine std::unordered_map nicht ausreichen (musst du wirklich zu jedem Zeitpunkt nach dem Key sortiert über die Elemente iterieren können)?

@Roflo: Danke für den Hinweis, allerdings sind nur maximal 4-5 Einheiten auf einer Raute, dadurch ist die Liste sehr kurz. Ich denke, dass sich Vector und Liste da nichts nehmen.

Wenn es keinen bestimmten Grund gibt, aus dem du wirklich eine std::list brauchst, solltest du std::vector verwenden. Gerade im von dir genannten Fall wird der std::vector stark im Vorteil sein...

8

02.01.2016, 16:10

Du kannst auch einfach, statt operator[] die korrespondiere Funktion at verwenden, die in einem solchen Fall nicht einfach eine neue Liste erstellt, sondern eine Exception wirft. beispiel

MfG
Check

9

02.01.2016, 16:32

@dot:

Ad 1)

Sehr interessant, ich habe die std::unordered_map bis jetzt noch nicht wahrgenommen. Da ich lediglich meine Keys möglichst schnell finden muss und mir die Reihenfolge dabei herzlich egal ist, habe ich das geändert. Danke :)

Ad 2)
Um ehrlich zu sein, über std::vector und std::list habe ich mir nicht viele Gedanken gemacht. Ich bin auch nicht der fitteste mit allen unterschiedlichen Containern von C++.

Weshalb ist std::vector an diese Stelle von größerem Vorteil?

@Checkmateinq:

Danke für den Hinweis und den Beispielcode, mit Exception ist das eine sehr elegante Lösung :)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

02.01.2016, 16:59

Weshalb ist std::vector an diese Stelle von größerem Vorteil?
Wegen der konstanten Zugriffszeit und Cache-freundlichem Verhalten bei linearer Iteration.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige