je rencontre quelques problèmes qui peuvent être repris par le morceau de code suivant:C++ fonctions comme arguments de modèle
template <typename Key, typename Data, typename fct>
size_t wrapper(const std::pair<Key, Data> & p)
{
return fct(p.first);
}
int main(int argc, char *argv[])
{
size_t val =
wrapper<int, int, dft_hash_fct<int>>(std::pair<int,int>(5,9));
return 0;
}
J'utilise la version du compilateur clang 3.4 et ce code ne compilent pas avec l'erreur suivante
test-tmp.C:17:5: error: no matching function for call to 'wrapper'
wrapper<int, int, dft_hash_fct<int>>(std::pair<int,int>(5,9));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test-tmp.C:9:8: note: candidate template ignored: invalid explicitly-specified argument
for template parameter 'fct'
l'idée est d'envelopper une fonction de hachage (le paramètre de modèle fct
) sur std::pair
pour ne prendre que le premier champ.
dft_hash_fct
est un autre modèle définit comme suit:
template <typename Key>
size_t dft_hash_fct(const Key & key)
{
return SuperFastHash(key);
}
Cette fonction générique fonctionne; il a été utilisé dans d'autres contextes.
Le but de tout ceci est de réutiliser un ensemble basé sur le hachage (pas de carte) comme une carte de clés pour des éléments de n'importe quel type. Le ser basé sur le hachage reçoit une fonction de hachage dans le temps de construction.
Merci pour vos commentaires (David, Andreï et Kazark)
Modifié:
Eh bien, je vois, typename fct est un type, donc je ne peux pas gérer en fonction de pointeur; désolé pour le trivia. Malheureusement, je crois que l'approche du passage de la fonction en tant que paramètre dans l'emballage ne fonctionne pas, parce que l'ensemble de hachage attend un pointeur de fonction avec la signature suivante:
size_t (*the_function)(const Key & key);
Alors, réalisant cela, grâce à vos observations, J'ai changé le code en question à:
template <typename Key, typename Data, size_t (*fct)(const Key & k)>
size_t wrapper(const std::pair<Key, Data> & p)
{
return (*fct)(p.first);
}
int main(int argc, char *argv[])
{
size_t val =
wrapper<int, int, dft_hash_fct<int>>(std::pair<int,int>(5,9));
return 0;
}
qui compile, relie et s'exécute. En outre, j'ai mis cette ligne:
size_t (*fct)(const std::pair<int, int>&) =
wrapper<int, int, dft_hash_fct<int>>;
cout << (*fct)(std::pair<int, int>(4,6)) << endl;
Et cela compile, relie et fonctionne aussi. Donc, je peux dire que le compilateur (et bien sûr selon le langage) peut instancier la fonction et gérer un pointeur de fonction. Donc, après cela, j'ai essayé de modifier mon code original, qui est une classe dérivée de HAshSet destinée à gérer des paires hachées par le premier champ.
Je déclare certains comme:
template <typename Key, typename Data>
class HashMap : public HashSet<std::pair<Key, Data>>
{
...
HashMap(size_t (*function)(const Key & key))
: HashSet<Key, Data>(wrapper<Key, Data, function>)
{
}
..
};
Mais la compilation (avec std = C++ 11) échoue avec l'erreur
./tpl_dynSetHash.H:353:7: error: no matching constructor for initialization of
'HashSet<std::pair<unsigned long, long>>'
: HashSet<std::pair<Key,Data>(
^
testDynSetHash.C:178:8: note: in instantiation of member function
'HashMap<unsigned long, long>::HashMap' requested here
HMap table;
Cependant, si je remplace l'appel au constructeur de base par
: HashSet<Key, Data>(wrapper<Key, Data, dft_hash_fct<Key>)
Cela compile bien. Ainsi, je crois que le problème est avec la déclaration de type de paramètre (mais je ne sais pas ce que c'est).
Vous devez fournir un type pour un argument de modèle de type, mais vous avez fourni une fonction. – dyp
Vous utilisez clang ++ 3.4, pouvez-vous/êtes-vous autorisé à utiliser les fonctionnalités C++ 11? – dyp
1) Il vous manque un '' 'à la fin de' wrapper 'dans votre dernier bloc de code. 2) 'HashMap (size_t (* fonction) (const Clé et clé)): HashSet (wrapper )' n'est pas possible car 'function' n'est pas une constante de compilation ici (mais une fonction paramètre); Seules les constantes de compilation (expressions constantes) sont autorisées en tant qu'arguments de modèle non-type (je fais référence au troisième argument de 'wrapper <..>'). –
dyp