模板专门化在链接时失败

时间:2011-07-15 09:16:50

标签: 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”方法,所以链接器应该能够从目标文件中获取。相反,如果我将方法放在源文件中,我会得到一个未解决的链接器引用错误:

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

如果我将此方法作为内联放在头文件中,那么构建就可以了。我理解模板的功能如下:

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

应放在标题中,因为编译器无法根据调用代码对模板进行专门化,但在完全特化的情况下,它是类的实现,因此专用模板方法应该已经作为公共符号存在。有人可以对这个问题有所了解吗?

3 个答案:

答案 0 :(得分:11)

您的分析是正确的 - 一个显式专用的函数模板,其中包含使用显式值指定的任何模板参数,它提供了函数的完整定义。

如果您已将包含显式特化定义的相应.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>。那是因为任何这样的调用都不会看到显式的特化声明,因此会尝试从模板定义中实例化该函数。标准使得此类代码格式不正确,无需诊断。

答案 1 :(得分:0)

专门化模板不会强制编译器实例化它(我认为GCC会这样做);您仍然需要明确告诉编译器实际实例化模板。您可以使用显式模板实例化来完成此操作。基本上,只需在源文件中添加它:

template std::string VariableManager::get(const std::string& name) const;

答案 2 :(得分:0)

template<>开头的方法仍被视为template 专业化方法。所以你必须放入一个头文件。

如果您想将其放入实施文件中,则必须重载

class VariableManager
{
//...
  VarT get(std::string const& name) const
  {}

  std::string get(std::string const& name) const; //overloading not specialization
};
相关问题