我有一个带有构造函数的模板化类,它只接受一个参数;指向函数的函数指针,该函数接受第二个模板类型的参数。并返回第一个模板类型的元素。
以下是代码:
cache_controller.hpp:
template<class TYPE, class KEY>
class cache
{
private:
TYPE (*create_func)(KEY);
public:
cache(TYPE (*func)(KEY));
};
extern sf::Texture * create_texture(std::string path);
cache_controller.cpp:
template<class TYPE, class KEY>
cache<TYPE, KEY>::cache(TYPE (*func)(KEY))
{
this->create_func = func;
}
sf::Texture * create_texture(std::string path)
{
sf::Texture * tex_p = new sf::Texture;
tex_p->loadFromFile(path);
return tex_p;
}
测试代码:
cache<sf::Texture *, std::string> tcache(&create_texture);
然而,当我链接时,我收到此错误:
[Linker error] main.cpp:11: undefined reference to `cache<sf::Texture*, std::string>::cache(sf::Texture* (*)(std::string))'
当然,如果有更简单的方法来实现具有任意键,值和创建函数的对象缓存,我都是耳朵。
答案 0 :(得分:3)
您在.cpp
文件中提供模板类的成员函数的定义。
这些成员函数的定义必须在实例化时由编译器可见(即,从调用这些函数的.cpp
文件),否则只能看到它们的声明 ,并且编译器将依赖于在其他地方定义的函数,同时处理不同的转换单元。
由于在翻译单元中没有该函数的实例化(即.cpp
文件),其编译器可以看到它的定义,因此链接器最终会抱怨没有提供定义。
您应该将cache
的构造函数的定义放在头文件中,其中定义了类模板cache
(在您的情况下,cache_controller.hpp
)。
答案 1 :(得分:2)
模板化方法的实现必须与保存其声明的文件一致。模板实例化是编译时操作,而不是链接时。将两者合并到一起以解决链接器错误。也就是说,在类内部或外部但在同一文件中实现构造函数。