2017-01-13 1 views
1

J'ai créé une classe de hachage pour un type personnalisé que j'utilise, mais il a un constructeur qui prend un argument. Je ne peux pas comprendre la syntaxe à utiliser dans un unordered_set.Syntaxe pour passer l'argument à la fonction de hachage unordered_set en C++

class Hasher { 
    unsigned arg; 
public: 
    Hasher(unsigned a) : arg(a) {} 
    size_t operator()(const MyType& t) const { 
     return calculate_hash(arg, t); 
    } 
} 

int main() { 
    unordered_set<MyType, Hasher(2)> myset; // compilation error 
} 

Le message d'erreur:

In file included from Tetrahedron.cc:5: 
./Triangulation.h:52:29: error: template argument for template type parameter must be a type 
     unordered_set<TetraFace,FaceHasher(2)> faces2; 
           ^~~~~~~~~~~~~ 
/bin/../lib/gcc/x86_64-redhat-linux/6.3.1/../../../../include/c++/6.3.1/bits/unordered_set.h:90:11: note: template parameter is declared here 
     class _Hash = hash<_Value>, 
      ^

J'ai aussi essayé

unordered_set<MyType, Hasher> myset(Hasher(2)); 

mais je reçois encore une erreur:

In file included from Tetrahedron.cc:5: 
./Triangulation.h:52:59: error: expected ')' 
    unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2)); 
                 ^
./Triangulation.h:52:58: note: to match this '(' 
unordered_set<TetraFace,FaceHasher> faces2(FaceHasher(2)); 
                ^

Répondre

2

Vous obtenez une erreur de compilation parce que vous essayez de transmettre un objet (c'est-à-dire une instance) de type Hasher en tant qu'argument de modèle.

Comme votre erreur décrit: template argument for template type parameter must be a type

Il attend un type et vous passez une valeur.

Paramétrer l'argument au niveau du type.

template<unsigned A> 
class Hasher { 
    unsigned arg = A; 
public: 
    size_t operator()(const int& t) const { 
     std::cout << arg << std::endl; 
     return 0; 
    } 
}; 

int main() { 
    std::unordered_set<int, Hasher<2>> myset; 
    myset.insert(5); // prints 2 

    std::unordered_set<int, Hasher<3>> myset2; 
    myset2.insert(3); // prints 3 
} 
0

Malheureusement, il est impossible de construire un std::unorderd_set avec juste t il hash objet. All of the constructors qui prennent l'objet de hachage ont un paramètre devant lui pour bucket_count. Vous devez spécifier la valeur comme

unordered_set<MyType, Hasher> myset(some_bucket_count_value, Hasher(2)); 

Si vous ne voulez pas faire cela, alors vous devez faire Hasher par défaut constructible.

également pas

return calculate_hash(arg); 

ne va pas travailler comme vous toujours hachage arg peu importe ce que vous passez MyType. Vous devez être hashing l'objet MyType pour que le std::unordered_set fonctionne vraiment.

+0

Oui, calculate_hash était juste un exemple pour montrer que j'ai besoin d'utiliser arg. Juste pour être sûr, vous avez dit unordered_map, mais il en va de même pour unordered_set, n'est-ce pas? – devil0150

+0

En outre, si je spécifie un nombre de segments initial, est-ce que C++ le gère en cas de besoin, ou dois-je le faire moi-même? – devil0150

+0

@ devil0150 Oups. C'est pareil pour un 'set'. Juste mis à jour la réponse. – NathanOliver