模板函数专业化的单独声明和定义:成员函数和非成员函数的不同行为

时间:2013-04-24 22:23:23

标签: c++ templates visual-c++ template-specialization function-templates

我想声明函数模板的特化,但稍后在源文件中定义它。考虑下一个例子:

.hpp

// approach #1
template <typename T> const char *GetTypeName();
template <> const char *GetTypeName<int>();

// approach #2
template <typename T> class TypeName {static const char *Get();};
template <> const char *TypeName<int>::Get();

.cpp

// approach #1
template <> const char *GetTypeName<int>()
{
    return "int"
}

// approach #2
template <> const char *TypeName<int>::Get()
{
    return "int"
}

在MSVC 2012中(CTP 安装),两种变体都编译良好,但非成员变体(#1 )引发了链接器错误(未解析的外部,blah)。这是正常的行为吗? MSVC具体?编译错误?在CTP中修复了吗?

修改
我只使用专门版本。它们在标头中声明并在源中定义。这种方法适用于成员,但不适用于独立功能。

编辑2
嗯......我试图在家里建立相同的快照(相同的MSVC安装,没有CTP),它没有问题链接。看起来像本地错误或安装损坏。

1 个答案:

答案 0 :(得分:2)

功能模板不是功能。一个完全专业化的函数模板一个函数。

由于必须定义所有(odr-used)函数,因此必须有一种方法来为任意模板实例化生成定义。因此,主要功能模板的定义必须在标题中。

<强> header.h:

template <typename T>            //  this
const char * GetTypeName()       //  is
{                                //  not
    return "foo";                //  a
}                                //  function

template <>
const char * GetTypeName<int>();

<强> impl.cpp:

#include "header.h"

template <>
const char * GetTypeName<int>()
{
    return "int";
}