Я использую статические члены шаблона в классе; шаблоны создаются в 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);
Об этом много раз спрашивали … объявление и определения для шаблонов должны быть в одном файле.