C++ 类模板成员专门化

C++ 类模板成员专门化,c++,specialization,class-template,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; } #pragma一次 #包括 模板 结构测试

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

#pragma once

#include <iostream>

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

template<>
void Test<int>::Print()
{
    std::cout << "int" << std::endl;
}
#pragma一次
#包括
模板
结构测试
{
无效打印(){}
};
模板
无效测试::打印()
{

std::cout将专门化放在头文件中是规范形式(正如boost所做的那样),它不违反ODR。

ODR要求ODR使用的非内联函数只有一个定义(对于函数来说,粗略的意思是可能被调用)

引用n3485[basic.def.odr]

4每个程序应仅包含一个 odr中使用的每个非内联函数或变量 编程;无需诊断

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

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

[我的重点]

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


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

您能提供一个例子说明boost是如何做到这一点的吗?我想知道ODR对于模板专门化有一个明确的例外“没有指定某些模板参数”,但就我所见,不是显式(=完全)专门化。如果我将此代码包含在两个不同的文件中并实际使用
Test::Print
(使用g++4.8.1),我确实会收到链接器错误。VS2013中没有链接器错误。(即使两个定义不同,也不会发出警告或任何东西。)