Мой полный код является слишком длинным, но здесь является отрывком, который отразит сущность моей проблемы:
class BPCFGParser {
public:
...
...
class Edge {
...
...
};
class ActiveEquivClass {
...
...
};
class PassiveEquivClass {
...
...
};
struct EqActiveEquivClass {
...
...
};
struct EqPassiveEquivClass {
...
...
};
unordered_map, EqActiveEquivClass> discovered_active_edges;
unordered_map, EqPassiveEquivClass> discovered_passive_edges;
};
namespace std {
template <>
class hash
{
public:
size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const {
}
};
template <>
class hash
{
public:
size_t operator()(const BPCFGParser::PassiveEquivClass & pec) const {
}
};
}
Когда я компилирую этот код, я получаю следующие ошибки:
In file included from BPCFGParser.cpp:3,
from experiments.cpp:2:
BPCFGParser.h:408: error: specialization of ‘std::hash’ after instantiation
BPCFGParser.h:408: error: redefinition of ‘class std::hash’
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of ‘class std::hash’
BPCFGParser.h:445: error: specialization of ‘std::hash’ after instantiation
BPCFGParser.h:445: error: redefinition of ‘class std::hash’
/usr/include/c++/4.3/tr1_impl/functional_hash.h:44: error: previous definition of ‘class std::hash’
Теперь я должен специализировать станд.:: хеш для этих классов (потому что стандартный станд.:: определение хеша не включает определяемые пользователем типы). Когда я перемещаю эти шаблонные специализации перед определением класса BPCFGParser
, Я получаю множество ошибок для множества разных вещей, которые попробовали, и где-нибудь (http://www.parashift.com/c++-faq-lite/misc-technical-issues.html), я считал что:
Каждый раз, когда Вы используете класс в качестве шаблонного параметра, объявление того класса должно быть полным и не просто передать объявленный.
Таким образом, я застреваю. Я не могу специализировать шаблоны после BPCFGParser
определение, я не могу специализировать их прежде BPCFGParser
определение, как я могу получить эту работу?
Необходимо переместить специализацию во внутренний класс в BPCFGParser. Выполнение так отвечает обоим требованиям.
Большое спасибо за ответ :)
hash
класс определяется в пространстве имен std
. Это не позволяет мне специализировать шаблоны для hash
в объеме непространства имен. Даже следующее:
template <>
class std::hash {
...
не работал. Когда я включаю специализации с namespace std {}
, однако, это дает странную ошибку:
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
В ответе, данном в velocityreviews, кто-то утверждает, что пространства имен не могут быть определены в классах. Таким образом, я все еще застреваю.
You need to move the specialization into an inner class inside of BPCFGParser. Doing so meets both requirements
ActiveEquivClass
Example:
class BPCFGParser {
class ActiveEquivClass {
...
};
template <>
class hash<ActiveEquivClass> {
public:
size_t operator()(const BPCFGParser::ActiveEquivClass & aec) const {
}
};
...
unordered_map<ActiveEquivClass, Edge *, hash<ActiveEquivClass>, EqActiveEquivClass> discovered_active_edges;
};
Попробуйте переместить код специализации шаблона hash <> перед объявлением класса BPCFGParser. Ошибка означает, что хеш расширяется на основе std :: hash, определенного в /usr/include/c++/4.3/tr1_impl/functional_hash.h; Таким образом, ваша специализация не используется до создания экземпляра. В идеале код вашей специализации должен быть доступен для компилятора до того, как шаблон будет расширен.