我在.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说明符时,我不再有错误
在基本级别上,实例化模板类仅实例化类定义,而不是成员函数的定义。
现在,类模板的显式实例化也明确地实例化直接(非基类,非模板)成员:
[temp.explicit]#10(强调我的)
命名类模板特化的显式实例化也是其每个成员(不包括从基类继承的成员和作为模板的成员)的相同类型(声明或定义)的显式实例化,这些实例之前未明确专门化包含显式实例化的转换单元,前提是该成员的关联约束(如果有)由显式实例化([temp.constr.decl],[temp.constr.constr])的模板参数满足,除非如下面所描述的。 [注意:此外,它通常是关于类的某些依赖于实现的数据的显式实例化。 - 结束说明]
注意:
EXPL。研究所。声明= extern template MyClass<Args>;
,expl。研究所。定义= template MyClass<Args>;
但是,这仅适用于在实例化时实际定义的成员:
[temp.explicit]#11(强调我的)
命名类模板特化的显式实例化定义显式实例化类模板特化,并且是仅在实例化时定义的那些成员的显式实例化定义。
由于您在标头中执行了显式实例化定义(源文件包含该定义),因此成员函数的定义在您对类模板进行显式实例化之后,因此这些函数也未显式实例化。
因此,建议仅在源文件末尾执行(非extern
)类模板的显式实例化,以完全定义其中的所有内容。头文件肯定是错误的地方。