Я использую статические члены шаблона в классе; шаблоны создаются в 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, содержащий экземпляр шаблона в моем подключаемом модуле?
Поскольку вы связываете исходный файл, содержащий явные специализации, перед тем, как вы их определяете, вам нужно объявить свои явные специализации. Из п. 14.7.3/3:
Объявление шаблона функции, шаблона класса или шаблона переменной, явно специализированного, предшествует объявлению явной специализации. [Примечание. Требуется декларация, но не определение шаблона. - конечная нота]
Поэтому вам нужно поместить их после своего класса в файл заголовка:
template<>
QString MenuInterface::name(ToplevelMenuElement elt);
template<>
QString MenuInterface::name(FileMenuElement elt);
template QString MenuInterface::name(ToplevelMenuElement)
...)
Это задано много раз... Объявление и определения для шаблонов должны быть одного и того же файла.