2

I'm specializing member functions of a template class in a header file like so:

#pragma once

#include <iostream>

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

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

Is it correct to put the specialization in a header file (without it being inline), or should it be in a cpp file? It compiles fine as shown above (using VS2012), but I'm rather surprised I don't get multiple definition linker errors.

4

2 回答 2

2

ODR 需要对ODR 使用的非内联函数有一个确切的定义(这对于函数来说粗略意味着可能被调用)。

引用 n3485,[basic.def.odr]

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

然后,模板有一个例外(即不是函数):

6类类型 [...]、类模板、非静态函数模板、类模板的静态数据成员、类模板的成员函数或模板特化可以有多个定义,其中某些模板参数未在程序中指定,前提是 [...]

[强调我的]

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

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

于 2014-03-22T18:19:08.503 回答
1

将专业化放在头文件中是规范形式(就像boost那样),它不违反 ODR。

于 2014-03-22T18:04:13.280 回答