静态字段模板特化的“未定义引用”

时间:2011-12-25 05:10:17

标签: c++ templates static linker

我有一个模板类标题,它只有静态函数和字段。

template<typename T> class Luaproxy {

    static std::map<std::string, fieldproxy> fields;
    static const char * const CLASS_NAME;
    static void addfields();
    static int __newindex(lua_State * l){
        //implemented stuff, references to fields...
    }
    //etc
}

正如您所看到的,只有一些函数被声明,因为我打算用模板特化来实现它们。

在.ccp文件中我有:

struct test { int a; }
template<> map<string, fieldproxy> Luaproxy<test>::fields;
template<> const char * const Luaproxy<test>::CLASS_NAME=typeid(test).name();
template<> void Luaproxy<test>::addfields(){
    //stuff, references to fields...
}

我从头文件中实现的两个函数和仅专门用于.cpp的函数中获取Luaproxy<test>::fields未定义的引用错误。请注意,似乎在链接中找到了Luaproxy<test>::CLASS_NAMELuaproxy<test>::addfields

是什么让map如此特别?

2 个答案:

答案 0 :(得分:5)

我终于设法让它工作了,但我无法真正说出为什么我的编译器(gcc 4.6.1)需要这样:template<> std::map<std::string, fieldproxy> Luaproxy<test>::fields=std::map<std::string, fieldproxy>();

显式构造函数似乎说服gcc有效地发出变量。我要求#gcc澄清,但不幸的是,该频道总是保持沉默。

答案 1 :(得分:2)

我在VC9中用几个额外的分号和命名空间标记构建了你的代码,但既没有编译错误也没有链接错误。

这是我建立的:

Luaproxy.h文件:

#pragma once
#include <map>
#include <string>
typedef int fieldproxy;
struct lua_State;
struct test {
    int a;
};
template<typename T>
class Luaproxy
{
public:
    static std::map<std::string, fieldproxy> fields;
    static const char * const CLASS_NAME;
    static void addfields();
    static int __newindex(lua_State * l){}
};

Luaproxy.cpp文件:

#include "Luaproxy.h"
template<> std::map<std::string, fieldproxy> Luaproxy<test>::fields;
template<> const char * const Luaproxy<test>::CLASS_NAME=typeid(test).name();
template<> void Luaproxy<test>::addfields(){}

main.cpp文件:

#include "Luaproxy.h"
int _tmain(int argc, _TCHAR* argv[])
{
    Luaproxy<test> *p = new Luaproxy<test>;
    p->fields["foo"] = 0;
    delete p;
    return 0;
}