Ale*_*lex 1 c++ templates static-variables
我有一个模板化的类叫PooledResource.它为我处理像纹理和声音这样的事情,并确保我不会在事故中多次加载同一个.某种类型的资源将始终位于某个子目录中,我希望能够更轻松地加载它们,因此我决定添加一个静态变量来跟踪某种类型资源的根文件夹.
template <typename T>
class PooledResource
{
public:
// ...
static const char* PathPrefix;
static ResourceTable myResourceTable;
static void load(const char* filename)
{
// Any attempt to use PathPrefix in here causes a compilation error
// All I want to do is use PathPrefix and filename to get the full
// path do a file and load it.
}
};
template <typename T>
const char* PooledResource<T>::PathPrefix = NULL;
template <typename T>
typename PooledResource<T>::ResourceTable PooledResource<T>::myResourceTable;
Run Code Online (Sandbox Code Playgroud)
我的想法是我可以为各种类型使用typedef'd版本.例如,PooledTexture.hpp我会:
typedef PooledResource<Texture> PooledTexture;
Run Code Online (Sandbox Code Playgroud)
在PooledTexture.cpp我会:
template <>
const char* PooledTexture::PathPrefix = "../assets/textures/";
Run Code Online (Sandbox Code Playgroud)
如果我不尝试在上面的加载函数中使用PathPrefix,这将编译并运行正常.一旦我使用它,我会得到这样的错误:
90 || CMakeFiles/game.dir/PooledTexture.cpp.o:(.data+0x0): multiple definition of `ag::PooledResource<sf::Texture>::PathPrefix'
91 CMakeFiles/game.dir/lua/LuaFrame.cpp.o:/usr/include/c++/4.6/i686-linux-gnu/./bits/gthr-default.h|241| first defined here
Run Code Online (Sandbox Code Playgroud)
我尝试用一个更简单的案例来复制这个以试图找到问题,但我尝试的其他情况似乎工作.我不确定我在做什么不同会导致这个错误.
这里的问题是你的变量空间是在标题中分配的,然后由多个编译单元包含 - LuaFrame.cpp.o和PooledTexture.cpp.o.附注:命名您的目标文件.cpp.o令人困惑.
因此,有两个具有相同名称的变量.
您需要将实际的空间分配(不是声明,而是分配它的位)移动到cpp文件而不是标题中,然后将其与应用程序的其余部分一起构建.是的,你现在在标题中有它:你设置它的位NULL!
编辑:当你这样做时,头部将不再有足够的信息来创建模板的一个实例,所以你必须明确实例化类与要使用它的每个类型.