2013-02-09 243 views
0

我有一个带有构造函数的模板类,它只接受一个参数;一个指向第二个模板类型参数的函数的函数指针。并返回第一个模板类型的元素。在C++类构造函数中的函数指针

下面的代码:

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); 

然而,当我联系我得到这个错误R:

[Linker error] main.cpp:11: undefined reference to `cache<sf::Texture*, std::string>::cache(sf::Texture* (*)(std::string))' 

当然,如果存在实现与arbitary键,值和创造功能我洗耳恭听的对象缓存,任何更简单的方法。

+0

请注意,将模板参数以相反方式放置会更常见,类似于std :: map或其他关联容器:'cache '(key = >值) – leemes 2013-02-09 14:05:54

回答

3

您提供了.cpp文件中模板类的成员函数的定义。

的那些成员函数的定义必须是编译器在实例化点(即,从.cpp文件调用这些函数)可见,否则只有自己声明可以看出,编译器将仅仅依靠该功能在其他地方定义,同时处理不同的翻译单元。

由于在编译器可以看到其定义的翻译单元(即.cpp文件)中没有该函数的实例化,所以不会生成任何实例,并且链接器最终会抱怨没有提供定义。

你应该把cache的构造函数的定义放在定义类模板cache的头文件中(在你的例子中为cache_controller.hpp)。

+0

我是一个忘了那个白痴。谢谢。 – Mloc 2013-02-09 14:02:36

+1

@Mloc:不用担心,我们都在那里。 – 2013-02-09 14:02:57

2

模板化方法的实现必须与保存其声明的文件一致。模板实例化是编译时操作,而不是链接时间。将两者互相合并,以解决链接器错误。也就是说,在类或外部实现构造函数,但在同一个文件中。