I have a templated class with a constructor which takes a single argument; a function pointer to a function that takes an argument of the second template-type. and returns an element of the first template-type.
Here’s the code:
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;
}
Test code:
cache<sf::Texture *, std::string> tcache(&create_texture);
However, when I link I get this error:
[Linker error] main.cpp:11: undefined reference to `cache<sf::Texture*, std::string>::cache(sf::Texture* (*)(std::string))'
Of course, if there are any easier ways to implement an object cache with arbitary keys, values and creation functions I’m all ears.
You provide a definition for member functions of a template class in a
.cppfile.The definition of those member functions must be visible to the compiler at the instantiation point (i.e., from the
.cppfile that invokes those functions), otherwise only their declaration will be seen, and the compiler will just rely on that function being defined somewhere else, while processing a different translation unit.Since there is no instantiation of that function in the translation unit (i.e.
.cppfile) where its definition is visible to the compiler, none will be generated, and the linker will eventually complain that no definition is provided.You should put the definition of
cache‘s constructor in the header file where class templatecacheis defined (which is, in your case,cache_controller.hpp).