类模板成员专业化

时间:2014-03-22 17:54:15

标签: c++ specialization class-template

我在头文件中专门化模板类的成员函数,如下所示:

#pragma once

#include <iostream>

template<class T>
struct Test
{
    void Print() { }
};

template<>
void Test<int>::Print()
{
    std::cout << "int" << std::endl;
}

将专门化放在头文件中(没有内联)或者是否应该在cpp文件中是否正确?它如上所示编译得很好(使用VS2012),但我很惊讶我没有得到多个定义链接器错误。

2 个答案:

答案 0 :(得分:2)

ODR对 ODR-used 的非内联函数只需要一个定义(粗略意味着,对于函数,可能被称为)。

引用n3485,[basic.def.odr]

  

4 每个程序都应该只包含一个定义   每个非内联函数或变量,其中使用的是odr   程序;无需诊断。

然后, templates 有一个例外(即不适用于函数):

  

6 类类型[...],类模板,非静态函数模板,静态数据成员可以有多个定义   类模板,类模板的成员函数或模板特化   在[...]

提供的程序中未指定某些模板参数

[强调我的]

模板的显式特化不是模板。例如,显式专用的类模板是一个类(具有奇怪的名称)。因此,您的假设是正确的,并且明确专门的类模板成员的多个定义违反了ODR。

使用g ++ 4.8.1,我甚至在这样的程序中遇到链接器错误;请注意我有ODR使用该功能。违反ODR无需诊断。

答案 1 :(得分:1)

将标题文件中的特化作为规范形式(如boost所做),它不会违反ODR。