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

12.01.2014, 19:45

std::map funktioniert mit C++ nicht mehr wie vorher

Hallo,

ich habe seit neustem Visual Studio 2012 und habe nun das Problem das std::map nicht mehr so funktioniert wie früher. Bis jetzt habe ich das hinzufügen von Elementen immer so gelöst:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
    it = map.find(ID);
    if(it != map.end())
    {
        std::string error("element mit ID: ");
        error.append(ID);
        error.append(" extistiert bereits.");
        throw std::exception(error.c_str());
    }
    map[ID] = element;


Wenn ich das jetzt genauso ausführe erhalte ich 6 Fehler die auf den xstddef verweisen. Hat sich mit C++11 irgentwas bei den maps verändert?

2

12.01.2014, 19:52

Zeig mal die Deklaration der map und der ID.
Ist so eig. okay.

MfG
Check

3

12.01.2014, 19:59

Hier die Deklaration der map:

C-/C++-Quelltext

1
std::map<std::string,element> map;


ID ist ein stringparameter.

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

4

12.01.2014, 20:38

Welchen typ hat denn it? und wie sind die fehlermedlungen genau?

Alternativ kannst du auch einfach insert verwenden. insert wird das neue element nur einfügen, wenn noch keins vorhanden ist.
Außerdem kannst du über den rückgabetyp herausfinden, ob das der fall war:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
auto result = map.insert(std::make_pair(ID, element));
// result ist vom typ pair<iterator, bool>. dem bool kannst du entnehmen, ob das element erfolgreich eingefügt wurde.
// also result.second ist true, wenn das element noch nicht existiert hat.
if(result.second == false)
{
        std::string error("element mit ID: ");
        error.append(ID);
        error.append(" extistiert bereits.");
        throw std::runtime_error(error);
}


Damit ist auch die performance besser, weil die map nur einmal durchsucht werden muss. Naja never mind :rolleyes:

5

12.01.2014, 20:45

Ok zum einem solltest du mal schauen, "element" scheint ja eine Klasse zu sein, da ist deine Zuweisung nicht gültig. Solltest du das allerdings abgeändert haben ists ja auch egal.
Nun zum Hauptaugenmerk:

C-/C++-Quelltext

1
#include <string>

und der Fehler ist behoben. Das liegt daran, dass der Container std::map die Elemente gleich ordnen möchte und er den <-Operator für std::string nicht finden kann, der jedoch in string definiert ist.
Warum eigentlich map und nicht std::vector?

MfG
Check

6

12.01.2014, 20:59

@Databyte Hört sich gut an, danke :)

Zitat

#include <string>
Danke.

Ich benutze hier map da es eine Statemanager Klasse ist und ich so einfach den Namen des States als Parameter übergebe um in diesen zu gehen.
Normalerweise benutze ich auch std::vector keine Sorge^^

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

7

13.01.2014, 18:03

Gerade bei so etwas Simplen bietet sich doch eher std::vector an, oder bei einer festen Zahl an States std::array, die du anhand eines Enums abklapperst. ôO Für jeden State ständig Strings vergleichen... Das wäre in Ordnung, wenn man wie in Lua unter Garantie keine doppelten Strings hätte, aber so... D;

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

8

13.01.2014, 23:23

Sein Anwendungsfall ist doch, dass er den Bezeichner eines States (der wohl einmalig unter allen States ist) hat und anhand dessen den State finden muss. Da bietet sich eine Datenstruktur, die die Daten in Form von Schlüssel-Wert-Paaren speichert an. Warum sollte dann dennoch eine Datenstruktur empfohlen wird, bei der die Elemente nur anhand ihrer Position in der Datenstruktur abgerufen werden können, kann ich nicht ganz nachvollziehen. (Ich bin kein C++ Programmierer, weshalb mir keine Besonderheiten des Typs std::map im Gegensatz zu vergleichbaren Strukturen anderer Sprachen bekannt sind.)
Würde kein Assoziatives Array verwendet werden, müsste bei jedem Abruf eines States potentiell die gesamte Liste (im Optimalfall nur das erste Element) geprüft werden, ob es der gewünschte ist.

Was meinst du mit "wenn man keine doppelten Strings hätte"?

Einen State an einem Enumerationswert zu erkennen, statt Strings zu verwenden, ist grundsätzlich keine unsinnige Idee, allerdings bringt das den Nachteil mit sich, dass für jeden evtl. hinzu kommenden State die Enumeration angepasst werden muss. wird der State Manager (wie im Wiki als Beispiel verwendet) für die Zustände des Spiels (oder allgemeiner: nur für eine einzige Sache) verwendet, mag das ja noch halbwegs in Ordnung sein, soll der Statemanager aber ganz allgemein gehalten sein und auch durch eine KI verwendet werden können, kann man die Enumeration wieder vergessen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Tankard

Treue Seele

Beiträge: 192

Beruf: Student, Hardware- und Softwareentwicklung als wissenschaftliche Hilfskraft

  • Private Nachricht senden

9

13.01.2014, 23:35

Würde kein Assoziatives Array verwendet werden, müsste bei jedem Abruf eines States potentiell die gesamte Liste (im Optimalfall nur das erste Element) geprüft werden, ob es der gewünschte ist.

Daher ja ein Zugriff über Enums.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef enum {
 STATE1,
 STATE2,
 .....
 STATE_N,
 STATE_COUNT
} state_t;

StateObject stateObjects[STATE_COUNT];

state_t state;

...

stateObjects[state].doSomething();


Zumindest hab ich sowas mal in C gemacht mit einem Array von Funktionspointern.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

10

13.01.2014, 23:51

[...], soll der Statemanager aber ganz allgemein gehalten sein und auch durch eine KI verwendet werden können, kann man die Enumeration wieder vergessen.


Außerdem würde ich es als besser empfinden, wenn der aktive State zwischengespeichert wird, nicht aber der aktuelle Index bzw. der Name des States.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige