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中没有链接器错误。(即使两个定义不同,也不会发出警告或任何东西。)