c++ - 模板特化在链接时失败

标签 c++ templates visual-c++

我有一个关于模板特化的问题,我想了解一下。我正在使用 Visual C++ 10.0 (2010)。我有这样一个类:

class VariableManager
{
public:

    template<typename VarT>
        VarT get(std::string const& name) const
        {
                    // Some code...
        }

   // This method supposed to be fully evaluated, linkable method.   
    template<>
        std::string get<std::string>(std::string const& name) const;

private:
    std::map<std::string, boost::any> mVariables;
};

理论上,因为我特化了“get”方法,链接器应该能够从目标文件中获取。相反,如果我将方法放在源文件中,链接器会出现 Unresolved 引用错误:

    template<>
    std::string VariableManager::get<std::string>(std::string const& name) const
            {
                 // Doing something...
            }

如果我将此方法作为内联方法放置在头文件中,则构建会进行得很好。我确实理解模板的功能是这样的:

        template<typename VarT>
            VarT get(std::string const& name) const;

应该放在 header 中,因为编译器将无法根据调用代码对模板进行特化,但在完全特化的情况下,类的实现会这样做,因此特化模板方法应该已经作为公共(public)符号存在。有人可以阐明这个问题吗?

最佳答案

您的分析是正确的 - 一个明确特化的函数模板,其任何模板参数都指定了显式值,提供了函数的完整定义。

如果你已经正确包含相应的.cpp将包含显式特化定义的文件添加到您的项目中,则 VC++ 不应引发链接器错误。不过,为了符合标准,请注意您必须在封闭类之外声明您的特化。该标准禁止在封闭类内声明显式特化(其他编译器将拒绝您的代码)。所以改变头文件来声明这样的特化,而不是

class VariableManager
{
public:

    template<typename VarT>
        VarT get(std::string const& name) const
        {
                    // Some code...
        }

private:
    std::map<std::string, boost::any> mVariables;
};

// This method supposed to be fully evaluated, linkable method.   
template<>
std::string VariableManager::get<std::string>(std::string const& name) const;

另外请注意,您不能调用 get<std::string>在你的类里面。那是因为任何这样的调用都不会看到显式的特化声明,因此会尝试从模板定义中实例化函数。该标准使此类代码格式错误,无需诊断。

关于c++ - 模板特化在链接时失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6704955/

相关文章:

C++哪个容器用于存储缓存内存

c++ - 更好的转换功能

C++ 模板 vector 操作重载

C++将png资源导出到文件

c++ - Vector中如何使用复制功能?

c++ - 如何将项目放入具有模板化父类(super class)类型的 vector 中

c++ - 设计 L-System 数据结构 (C++)

c++ - QTextEdit 和自定义滚动 - PageDown/PageUp

c++ - 字符数组和指针的区别

c++ - 如何为模板低音类的所有实例创建共享静态变量?