0

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

4

2 回答 2

2

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

显式特化的函数模板、类模板或变量模板的声明应在显式特化的声明之前。[注意:需要声明,但不需要模板的定义。——尾注]

所以你需要把这些放在你的头文件中你的类之后:

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

template<>
QString MenuInterface::name(FileMenuElement elt);
于 2014-11-17T18:42:56.813 回答
0

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

于 2014-11-17T18:32:09.387 回答