Шаблон неопределенной ссылки на окнах с MinGW 4.8

0

Я использую статические члены шаблона в классе; шаблоны создаются в cpp, встроенном в программное обеспечение. У меня есть плагин для программного обеспечения, которое использует метод шаблона name() в заголовке, но не создает исходный файл, содержащий экземпляр. Сборка работает на Linux с g++ - 4.9, но не работает на MinGW 4.8. Я хочу знать, как заставить его работать с почти таким же компилятором, но в Windows.

.hpp:

enum class ToplevelMenuElement
{
    FileMenu, 
    ...
    AboutMenu
};

enum class FileMenuElement
{
    New,
    ... ,
    Quit
};

// Others menus macros are defined

class MenuInterface
{
    public:
        template<typename MenuType>
        static QString name(MenuType elt);

    private:
        static const std::map<ToplevelMenuElement, QString> m_map;
        static const std::map<FileMenuElement, QString> m_fileMap;
};

.cpp:

template<>
QString MenuInterface::name(ToplevelMenuElement elt)
{
    return m_map.at(elt);
}

template<>
QString MenuInterface::name(FileMenuElement elt)
{
    return m_fileMap.at(elt);
}

const std::map<ToplevelMenuElement, QString> MenuInterface::m_map
{
    {ToplevelMenuElement::FileMenu, QObject::tr("File")},
    ...
    {ToplevelMenuElement::AboutMenu, QObject::tr("About")}
};

const std::map<FileMenuElement, QString> MenuInterface::m_fileMap
{
    {FileMenuElement::New, QObject::tr("New")},
    ..., 
    {FileMenuElement::Quit, QObject::tr("Quit")}
};

Ошибка:

undefined reference to 'QString MenuInterface::name<ToplevelMenuElement>(ToplevelMenuElement)'

Есть ли какой-либо флаг для создания своего рода ленивого экземпляра? Или я должен создать.cpp, содержащий экземпляр шаблона в моем подключаемом модуле?

  • 0
    Бесполезно писать метод шаблона, если его содержимое отличается в зависимости от типа параметра (ов).
  • 0
    @P0W P0W Это не похоже на дубликат, поскольку его код содержит явные специализации в файле cpp.
Показать ещё 5 комментариев
Теги:
c++11
templates
mingw
explicit-instantiation

2 ответа

2

Поскольку вы связываете исходный файл, содержащий явные специализации, перед тем, как вы их определяете, вам нужно объявить свои явные специализации. Из п. 14.7.3/3:

Объявление шаблона функции, шаблона класса или шаблона переменной, явно специализированного, предшествует объявлению явной специализации. [Примечание. Требуется декларация, но не определение шаблона. - конечная нота]

Поэтому вам нужно поместить их после своего класса в файл заголовка:

template<>
QString MenuInterface::name(ToplevelMenuElement elt);

template<>
QString MenuInterface::name(FileMenuElement elt);
  • 0
    Я только что попробовал, но я получаю те же неопределенные ошибки символов ...
  • 0
    @ Jean-MichaëlCelerier Попробуйте добавить явное создание экземпляра в исходный файл (например, template QString MenuInterface::name(ToplevelMenuElement) ...)
Показать ещё 3 комментария
0

Это задано много раз... Объявление и определения для шаблонов должны быть одного и того же файла.

  • 0
    Он прекрасно работает на Linux с gcc-4.9, поэтому я надеялся, что на MinGW будет то же самое ...
  • 0
    Только общие определения.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню