"неопределенная ссылка" на специализацию шаблона статического поля - PullRequest
4 голосов
/ 25 декабря 2011

У меня есть и заголовок с шаблоном класса, который имеет только статические функции и поля.

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...
}

Я получаю неопределенные ошибки ссылок на Luaproxy<test>::fields как от функций, которые реализованы в заголовке, так и от тех, которые специализируются только на .cpp. Обратите внимание, что Luaproxy<test>::CLASS_NAME и Luaproxy<test>::addfields, по-видимому, встречаются при связывании.

Что делает это map таким особенным?

Ответы [ 2 ]

5 голосов
/ 25 декабря 2011

Мне наконец удалось заставить его работать, но я не мог действительно сказать, почему мой компилятор (gcc 4.6.1) нуждается в этом следующим образом: template<> std::map<std::string, fieldproxy> Luaproxy<test>::fields=std::map<std::string, fieldproxy>();

Явный конструктор, кажется, убеждает gcc эффективно генерировать переменную. Я попросил у #gcc разъяснения, но, к сожалению, этот канал всегда молчит.

2 голосов
/ 25 декабря 2011

Я собрал ваш код с помощью нескольких дополнительных точек с запятой и тегов пространства имен в 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;
}
...