【问题标题】:"undefined reference" to static field template specialization对静态字段模板专业化的“未定义引用”
【发布时间】:2012-01-27 12:53:29
【问题描述】:

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

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&lt;test&gt;::fields 的未定义引用错误。请注意,Luaproxy&lt;test&gt;::CLASS_NAMELuaproxy&lt;test&gt;::addfields 似乎在链接中。

是什么让map 如此特别?

【问题讨论】:

  • 制作“模板类 Luaproxy;” cpp 文件顶部的条目。我认为必须解决它

标签: c++ templates static linker


【解决方案1】:

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

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

【讨论】:

    【解决方案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;
    }
    

    【讨论】:

    • 你的代码对我不起作用,这很奇怪。我的编译器是 gcc 4.6.1。一次偶然的机会,我向字段添加了显式构造函数声明,现在它可以编译了。在 3 小时内,我将能够自我回复并更深入地解释这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-13
    • 2016-06-16
    • 1970-01-01
    • 2020-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多