C ++ |Шаблоны и константный тип - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть объявление класса в файле .hpp:

template <typename Ressource, typename Identifier> class RessourceHolder {
public:
  void load(Identifier id, const std::string& filename);

  Ressource& get(Identifier id);
  const Ressource& get(Identifier id) const;


private:
  void insert(Identifier id, std::unique_ptr<Ressource> resource);


private:
  std::map<Identifier, std::unique_ptr<Ressource>> mRessourceMap;
};

template class RessourceHolder<sf::Texture, Textures::ID>;
typedef RessourceHolder<sf::Texture, Textures::ID> TextureHolder;

, которое включает в себя явную реализацию для RessourceHolder<sf::Texture,Textures::ID>.

И у меня есть реализация этого в отдельномФайл .cpp.Проблема заключается в следующем: позже я определяю const TextureHolder, и возникает следующая ошибка:
undefined reference to `RessourceHolder<sf::Texture, Textures::ID>::get(Textures::ID) const
Почему?

РЕДАКТИРОВАТЬ:
Как и просили, точка, гдепроблема возникает (файл hpp):

class Agent{
  public :
  Agent(TextureHolder const& textures);
  void setTexture();
  const TextureHolder& mTextures;
  private :
  sf::Sprite mSprite;
};

(файл cpp)

Agent::Agent(TextureHolder const& textures) : mTextures(textures){
  setTexture();
}
void Agent::setTexture(){
  mSprite.setTexture(mTextures.get(toTextureID(mType)));
}

Когда я удаляю спецификатор const в агенте, у меня больше нет ошибки

1 Ответ

0 голосов
/ 27 февраля 2019

На базовом уровне создание экземпляра класса шаблона только создает экземпляр определения класса, а не определения функций-членов.

Теперь явное создание экземпляра шаблона класса делает также явным образом созданнымпрямые члены (не из базового класса, без шаблонов):

[temp.explicit] # 10 (выделено мной)

An явное создание экземпляров, которое именует специализацию шаблона класса , также является явным созданием экземпляров того же вида (объявление или определение) каждого из его членов (не включая членов, унаследованных от базыклассы и члены, которые являются шаблонами), который ранее не был явно специализирован в модуле перевода, содержащем явную реализацию, при условии, что связанные ограничения, если таковые имеются, этого члена удовлетворяются аргументами шаблона явной реализации ([temp.constr.decl], [temp.constr.constr]), за исключением случаев, описанных ниже.[Примечание: Кроме того, обычно это будет явное создание определенных зависящих от реализации данных о классе.- примечание конца]

Примечание:
Expl.текущий месяц декларация = extern template MyClass<Args>;, экспл.текущий месяц определение = template MyClass<Args>;

Но , это делается только для членов, которые на самом деле определены в момент создания экземпляра:

[temp.explicit] # 11 (выделение мое)

Явное определение экземпляра, которое именует специализацию шаблона класса, явно создает экземпляр специализации шаблона класса и являетсяявное определение экземпляра только тех членов, которые были определены в момент создания .

Так как вы сделали явное определение экземпляра в заголовке (который включен источникомфайл), определения функций-членов приходят после вашего явного создания экземпляра шаблона класса, поэтому эти функции не также явно создаются.

Поэтому желательновыполнять только (не extern) явное создание экземпляра шаблона класса в конце исходного файла, который полностью определяет все в нем.Заголовочный файл, безусловно, не в том месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...