La spécialisation de template après l'instanciation?

Mon code est trop long, mais voici un extrait qui reflètent l'essence de mon problème:

class BPCFGParser {
public:
...
...
class Edge {
...
...
};
class ActiveEquivClass {
...
...
};
class PassiveEquivClass {
...
...
};
struct EqActiveEquivClass {
...
...
};
struct EqPassiveEquivClass {
...
...
};
unordered_map<ActiveEquivClass, Edge *, hash<ActiveEquivClass>, EqActiveEquivClass> discovered_active_edges;
unordered_map<PassiveEquivClass, Edge *, hash<PassiveEquivClass>, EqPassiveEquivClass> discovered_passive_edges;
};
namespace std {
template <>
class hash<BPCFGParser::ActiveEquivClass>
{
public:
size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const {
}
};
template <>
class hash<BPCFGParser::PassiveEquivClass>
{
public:
size_t operator()(const BPCFGParser::PassiveEquivClass & pec) const {
}
};
}

Quand je compile ce code, j'obtiens les erreurs suivantes:

In file included from BPCFGParser.cpp:3,
from experiments.cpp:2:
BPCFGParser.h:408: error: specialization of std::hash<BPCFGParser::ActiveEquivClass>’     after instantiation
BPCFGParser.h:408: error: redefinition of class                 std::hash<BPCFGParser::ActiveEquivClass>’
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of     class std::hash<BPCFGParser::ActiveEquivClass>’
BPCFGParser.h:445: error: specialization of     std::hash<BPCFGParser::PassiveEquivClass>’ after instantiation
BPCFGParser.h:445: error: redefinition of class std::hash<BPCFGParser::PassiveEquivClass>’
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of     class std::hash<BPCFGParser::PassiveEquivClass>’

Maintenant, j'ai à se spécialiser std::hash pour ces classes (parce que la norme std::hash définition n'inclut pas les types définis par l'utilisateur). Lorsque je déplace ces spécialisations de modèle avant la définition de la classe BPCFGParser, je reçois un certain nombre d'erreurs pour une variété de choses différentes essayé, et quelque part (http://www.parashift.com/c++-faq-lite/misc-technical-issues.html) j'ai lu que:

Chaque fois que vous utilisez une classe comme un paramètre du modèle, la déclaration de cette classe doit être complète et ne pas se contenter de transmettre déclaré.

Donc je suis coincé. Je ne peux pas spécialiser les modèles après BPCFGParser définition, je ne peut pas se spécialiser avant de BPCFGParser définition, comment puis-je le faire fonctionner?


Vous avez besoin de déplacer la spécialisation dans un intérieur de classe à l'intérieur de BPCFGParser. Ce faisant répond à ces deux exigences.

Merci beaucoup pour la réponse 🙂

hash classe est définie dans l'espace de noms std. Il ne me permet pas de me spécialiser les modèles pour hash dans un non-espace de noms de champ. Même les éléments suivants:

template <>
class std::hash<ActiveEquivClass> {
...

n'a pas de travail. Quand j'envoie les spécialisations avec namespace std {}, cependant, il donne l'erreur bizarre:

In file included from BPCFGParser.cpp:3,
from experiments.cpp:2:
BPCFGParser.h:225: error: expected unqualified-id before namespace
experiments.cpp:7: error: expected `}' at end of input
BPCFGParser.h:222: error: expected unqualified-id at end of input

Dans une réponse donnée dans velocityreviews, quelqu'un prétend que les espaces de noms ne peut pas être défini dans les classes. Donc, je suis toujours coincé.

OriginalL'auteur Onur Cobanoglu | 2009-12-12