具有 MinGW 4.8 的窗口上的模板未定义引用

Template undefined reference on windows with MinGW 4.8

本文关键字:未定义 引用 窗口 MinGW 具有      更新时间:2023-10-16

我在类中使用静态模板成员;模板在软件内置的cpp中实例化。我有一个软件插件,它在标头中使用name()模板方法,但不构建包含实例化的源文件。该构建在 g++-4.9 的 Linux 上运行,但在 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);

这已经被问了很多次了...模板的声明和定义应为同一文件。