Специализация шаблона после инстанцирования?

Мой полный код является слишком длинным, но здесь является отрывком, который отразит сущность моей проблемы:

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, кто-то утверждает, что пространства имен не могут быть определены в классах. Таким образом, я все еще застреваю.

7
задан Bill the Lizard 23 December 2011 в 12:42
поделиться

2 ответа

You need to move the specialization into an inner class inside of BPCFGParser. Doing so meets both requirements

  1. Specialization is after the complete definition of ActiveEquivClass
  2. Before the use of the specialization

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;

};
5
ответ дан 7 December 2019 в 07:46
поделиться

Попробуйте переместить код специализации шаблона hash <> перед объявлением класса BPCFGParser. Ошибка означает, что хеш расширяется на основе std :: hash, определенного в /usr/include/c++/4.3/tr1_impl/functional_hash.h; Таким образом, ваша специализация не используется до создания экземпляра. В идеале код вашей специализации должен быть доступен для компилятора до того, как шаблон будет расширен.

1
ответ дан 7 December 2019 в 07:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: