2017-05-14 2 views
2

Ich versuche, Conways "Game of Life" zu kodieren. Während näher an mein Ziel, immer habe ich mit einem Compiler-Fehler fest:"Die C++ Library stellt keinen Hash für diesen Typ bereit." - Eigene Klasse in std verwenden :: unordered_map

C2338: The C++ Library doesen't provide a hash for this type.

Zuerst habe ich die SFML Klasse sf::Vector2D. Als es für mich nicht funktionierte, schrieb ich eine eigene Klasse und hoffte, dass ich die fehlende hashCode Methode implementieren konnte.

Meine Frage ist:
Ist es möglich, für std::unordered_map meine eigene Klasse mit einer eigenen hashCode Methode verwendet? Ich muss eine Klasse verwenden, die zwei Zahlen enthalten kann. (Ich habe auch versucht std::tuple, struct und so).

Hier ist ein Blatt meines Code:

#include "GameMechanics.h" 



GameMechanics::GameMechanics(Elements * elements):elements(elements) 
{ 
    this->refreshTime = 1000000; //ms 
    this->clock.restart(); 
} 


GameMechanics::~GameMechanics() 
{ 
} 

bool GameMechanics::isRunning() 
{ 
    return this->running; 
} 

void GameMechanics::setRunning(bool running) 
{ 
    this->running = running; 
} 

void GameMechanics::loop() 
{ 

    unsigned passedTime = clock.getElapsedTime().asMicroseconds(); //check passed time since the clock got restarted 
    this->timeHeap += passedTime; //add passed time to the timeheap 
    this->clock.restart(); 
    //only refresh every "refreshTime" seconds 
    if (timeHeap >= this->refreshTime) {  
     std::cout << "Calculated new generation!" << std::endl; 
     this->timeHeap -= this->refreshTime; 
     this->calculateNextGeneration(); 
    } 
} 

void GameMechanics::calculateNextGeneration() 
{ 
    std::list<sf::Vector2i> oldGeneration = this->elements->getElements(); // population in the moment 

    sf::Vector2u elements = this->elements->getElementCount(); 

    std::unordered_map<MyVector2D, int> counter;  //here is the problem. Thats the line that makes some trouble 


    for (std::list<sf::Vector2i>::iterator it = oldGeneration.begin(); it != oldGeneration.end(); it++) { 
     sf::Vector2i position = *it; 

     for (int i = -1; i < 2; i++) 
     { 
      for (int j = -1; j < 2; j++) 
      { 
       if (position.x + i >= 0 && position.x + i <= this->elements->getElementCount().x && 
        position.y + j >= 0 && position.y + j <= this->elements->getElementCount().y) 
       { 
        if (counter.find(MyVector2D(position.x + i, position.y + j)) != counter.end()) 
        { 
         counter.at(MyVector2D(position.x + i, position.y + j))++; 
        } 
        else //if there is no such element, create a new entry 
        { 
         counter.insert({ MyVector2D(position.x + i, position.y + j),1 }); 
        } 
       } 
      } 
     } 
    } 


    //create new generation 
    this->brithNewGeneration(&counter); 
} 

void GameMechanics::brithNewGeneration(std::unordered_map<MyVector2D,int>* counter) 
{ 
    //this methode does work 

    std::list<sf::Vector2i> newGeneration; 
// for (std::unordered_map<MyVector2D, int>::iterator it = counter->begin(); it != counter->end(); it++) 
    { 
     //if life vell with < 2 neighbours, it dies 
     //life cell with 2 or 3 neighbours will continue living 

     //life cell with >4 cells will die 

     //dead cell with 3 neighbours will start living 
    } 
} 
+0

Nicht verwandt: Wenn Sie nicht ständig Elemente in der Mitte der Sequenz einfügen, ist 'std :: list' fast nie eine gute Containerwahl. –

Antwort

6

Die Funktion benutzerdefinierte Hashing für std::unordered_map erforderlich (und std::unordered_set) ist kein Mitglied Funktion des gespeicherten Typ. Sie müssen die std::hash Vorlage spezialisieren:

namespace std { 
    template<> 
    struct hash<YourType> { 
     using argument_type = YourType; 
     using result_type = std::size_t; 

     result_type operator()(argument_type const &obj) const { 
      // Compute and return the hash value for `obj`. 
     } 
    }; 
} 

Ihr Fall ist genau der Grund, warum es auf diese Weise getan hat: Sie std::hash für sf::Vector2D spezialisieren können, wenn Sie wollen, keine Notwendigkeit, eine eigene Klasse zu implementieren.

+1

Related: http://stackoverflow.com/a/38140932/214671; In diesem speziellen Fall würde mein 'MAKE_HASHABLE' Makro die gesamte Lösung auf' MAKE_HASHABLE (sf :: Vector2i, t.x, t.y) 'reduzieren. –

Verwandte Themen