3

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

.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)会引发链接器错误(未解决的外部问题,等等)。这是正常行为吗?MSVC 特定的?编译器错误?固定在 CTP 中?

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

编辑 2
嗯...我正在尝试在家中构建相同的快照(相同的 MSVC 安装,没有 CTP),并且链接没有问题。似乎是本地错误或损坏的安装。

4

1 回答 1

3

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

由于必须定义所有(odr 使用的)函数,因此您必须有一种方法来为任意模板实例化生成定义。因此主函数模板的定义必须在头文件中。

标头.h:

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

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

实现.cpp:

#include "header.h"

template <>
const char * GetTypeName<int>()
{
    return "int";
}
于 2013-04-24T22:35:38.153 回答