链接模板专业化失败 [英] Template specialization fails on linking

查看:140
本文介绍了链接模板专业化失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an issue with template specialization which I would like to understand. I'm working with Visual C++ 10.0 (2010). I have a class like this:

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

In theory, because I specialized the "get" method, the linker should be able to pick up from an object file. Instead, I get an unresolved reference error with the linker if I place the method in the source file:

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

如果我把这个方法放在头文件中作为inline,我明白模板的功能如下:

If I place this method in the header file as inline, the build goes just fine. I do understand that template functions as this:

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

应放置在标题中,因为编译器将无法根据调用代码,但在完全专业化的情况下,是类的实现,因此专用模板方法应该已经作为公共符号存在。

should be placed in the header because the compiler won't be able to specialize the template according to the calling code, but in the case of full specialization it is the class' implementation that does that thus the specialized template method should already exist as a public symbol. Could somebody throw some light on this issue?

推荐答案

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

Your analysis is correct - an explicitly specialized function template that has any template parameters specified with explicit values provides a complete definition of a function.

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

If you have properly included the corresponding .cpp file that contains the explicit specialization's definition into your project, then VC++ should not raise a linker error. For Standards compliance though, let me note that you have to declare your specialization outside of the enclosing class. The Standard forbids to declare explicit specializations inside of the enclosing class (and other compilers will reject your code). So change the header file to declare the specialization like this, instead

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> 。这是因为任何这样的调用不会看到显式专门化声明,因此将尝试从模板定义实例化函数。该标准使得此类代码不合格,无需诊断。

Let me also note that you can't call get<std::string> inside of your class body. That's because any such call would not yet see the explicit specialization declaration, and would hence try to instantiate the function from the template definition. The Standard renders such code ill-formed, without a diagnostic being required.

这篇关于链接模板专业化失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆