使用MinGW 4.8在Windows上模板未定义的引用

时间:2014-11-17 18:29:14

标签: c++ templates c++11 mingw explicit-instantiation

我在一个类中使用静态模板成员;模板在软件中构建的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吗?

2 个答案:

答案 0 :(得分:2)

因为您要链接包含显式特化的源文件,所以在定义它们之前需要声明显式特化。从§14.7.3/ 3开始:

  

明确专门化的函数模板,类模板或变量模板的声明应在声明显式特化之前。 [注意:需要声明,但不需要模板的定义。 - 结束说明]

所以你需要把你的课程放在你的头文件中:

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

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

答案 1 :(得分:0)

这已被多次询问......模板的声明和定义应该是同一个文件。