2013-05-29 7 views
0

Я реализую проблему шести Кевина Бэкона и записываю класс для узла актера. Я могу использовать set, но не hash_set для хранения определенного класса. Зачем? ошибка msg показывает: ошибка C2440: «тип cast»: невозможно преобразовать из «const ActorGraphNode» в «size_t» 1> Доступный пользовательский оператор преобразования не может выполнять это преобразование, или оператор не может быть вызван ... .не может содержать определенный пользователем класс в hash_set

#include <hash_set> 
#include <set> 
class ActorGraphNode{ 
    public: 
    string ActorName; 
    //hash_set<ActorGraphNode> linkedActors; 
    set<ActorGraphNode> linkedActors; 
    ActorGraphNode(string name):ActorName(name){} 
    void linkCostar(ActorGraphNode actor){ 
     linkedActors.insert(actor); 
     actor.linkedActors.insert(*this); 
    } 
    bool operator<(const ActorGraphNode& a) const 
    { return ActorName < a.ActorName ? true : false;} 
}; 

ответ

1

Unsurprisingly, hash_set требует для реализации хэш-функции для вашего типа.

class ActorGraphNode{ 
    public: 
    string ActorName; 
    hash_set<ActorGraphNode> linkedActors; 
    //set<ActorGraphNode> linkedActors; 
    ActorGraphNode(string name):ActorName(name){} 
    void linkCostar(ActorGraphNode actor){ 
     linkedActors.insert(actor); 
     actor.linkedActors.insert(*this); 
    } 
    bool operator<(const ActorGraphNode& a) const 
    { return ActorName < a.ActorName;} 
    bool operator ==(const ActorGraphNode& a) const 
    { return ActorName == a.ActorName;} 
    operator size_t() const 
    { 
     return hash<string>()(ActorName); 
    } 
}; 
+0

Вам также нужно равенство, а 'operator <' не требуется для контейнеров с неупорядоченным/хэш-кодом. –

+0

Равенство может быть сгенерировано компилятором, но, конечно, вы можете написать свой собственный, если, скажем, вы не хотите иметь накладные расходы на сравнение всего набора linkedActors. – riv

+0

Я думаю, что лучше сделать свою собственную специализацию для std :: hash вместо того, чтобы делать оператор size_t –

0

спасибо всем за ответы и комментарии ур. Вот мой обновленный код с вашей помощью. плюс для функции linkCostar() Я использую pass по ссылке:

class ActorGraphNode{ 
public: 
    string ActorName; 
    hash_set<ActorGraphNode> linkedActors; 
    ActorGraphNode(string name):ActorName(name){} 
    void linkCostar(ActorGraphNode& actor){ 
     linkedActors.insert(actor); 
     actor.linkedActors.insert(*this); 
    } 
    bool operator==(const ActorGraphNode& a) const 
    { return ActorName == a.ActorName ? true : false;} 
    operator size_t() const 
    { 
     const int HASHSIZE = 501; 
     int seed = 131; 
     size_t sum = 0; 
     for(size_t i = 0; i < ActorName.length(); ++i) 
      sum = (sum * seed) + ActorName[i];  
     return sum % HASHSIZE; 
    } 
}; 
+0

STL имеет хеш-функцию для строк, поэтому вам не нужно писать свои собственные; если вы это сделаете, не возвращайте результат по модулю 'HASHSIZE', вы в основном увеличиваете количество столкновений, заставляя свои значения 0 ... 500. – riv

+0

thx riv, здесь мое обновление для оператора size_t: \t operator size_t() const { хэш H; return H (ActorName); } – user389955

Смежные вопросы