内联函数模板特化

时间:2014-02-04 17:26:43

标签: c++

以下代码位于.h文件中(包含保护)

template<typename T1, typename T2> // a
void func(T1 const &t1, T2 const &t2)
{
    std::cout << "\nbase template"; 
}

template<> // b
inline void func<int, int>(int const &t1, int const &t2)
{
    std::cout << "\nspecialization for integers";
}

从(b)中删除inline关键字时,以下代码(从包含.h的.cpp调用)将无法编译

func<int, int>(1, 2);

发出链接器错误“错误LNK2005:”void __cdecl func(int const&amp;,int const&amp;)“(?? $ func @HH @@ YAXABH0 @ Z)已在ConsoleApplication1.obj中定义”

为什么会这样?

编辑:

因为它们是定义(由Luchian Grigore回答),显式特化是否意味着显式实例化或者这个编译器是否具体?

2 个答案:

答案 0 :(得分:5)

因为显式特化是定义,因此在多个翻译单元中包含该文件会导致多次定义符号,这会破坏一个定义规则。

除了标记inline之外,您可以将声明留在标题中并将定义移动到实现文件中。

答案 1 :(得分:2)

您只能使用类型本身直接覆盖它,而无需编写模板:

void func(int const &t1, int const &t2)
{
    std::cout << "\nspecialization for integers";
}

现在,错误发生是因为如果包含头部,那么如果在头部中定义的函数最终会出现在两个cpp文件中,那么将会有两个相同函数的声明(如错误所示:already defined)导致链接错误。要解决这个问题,只需在没有实现的情况下在头文件中编写声明,并在其中一个头文件中移动实现:

//header
void func(int const &t1, int const &t2);

//cpp file
void func(int const &t1, int const &t2)
{
...
}