Fas*_*ser 12 c++ templates inline template-specialization template-meta-programming
我指的是这个答案:
我遇到了与引用问题的OP类似的问题,有一个功能
template<typename T>
void func(T& val);
Run Code Online (Sandbox Code Playgroud)
及其专业化
template<>
void func<mytype>(mytype& val);
Run Code Online (Sandbox Code Playgroud)
导致重复的符号链接器错误(这些方法在我的标题末尾包含的'.tpp'文件中实现).添加inline
到专门的功能解决了这个问题.为什么?
Sto*_*ica 10
好吧,如果你想要标准的引用,那就在[temp.expl.spec]/12上结束了
函数或变量模板的显式特化只有在使用内联说明符声明或定义为已删除时才内联,并且与其函数或变量模板是否为内联无关.[例如:
Run Code Online (Sandbox Code Playgroud)template<class T> void f(T) { /* ... */ } template<class T> inline T g(T) { /* ... */ } template<> inline void f<>(int) { /* ... */ } // OK: inline template<> int g<>(int) { /* ... */ } // OK: not inline
- 结束例子]
这就是你必须这样做的原因.它是独立的,因为我认为否则会不必要地限制,正如Yola所证明的那样.
这将无内联工作:
file1.h
template<typename T> void func(T& val);
template<> void func<mytype>(mytype& val);
Run Code Online (Sandbox Code Playgroud)
file1.cpp
template<> void func<int>(int& ) {}
Run Code Online (Sandbox Code Playgroud)
但是,如果在头文件中定义模板特化,则可能违反ODR
根据c ++标准中的第3.2:4节
每个程序应该只包含该程序中使用的每个非内联函数或变量的一个定义; 无需诊断.该定义可以在程序中明确显示,可以在标准或用户定义的库中找到,或者(在适当的时候)隐式定义(见12.1,12.4和12.8).内联函数应在每个使用它的翻译单元中定义.
这解释了为什么在未声明内联专用函数时存在链接时错误.该程序将包含专用函数的多个定义,每个模块包含一个.tpp文件,这会破坏标准的条件.声明专用函数时,inline
它将使函数满足同一子句的第二部分,即必须使用函数在每个模块中定义内联函数.
当参数化函数不是专用函数时,它将在第3.2:6条中涵盖:
类类型(第9条),枚举类型(7.2),带内部链接的内联函数(7.1.2),类模板(第14条),非静态函数模板(14.5.6)可以有多个定义,类模板的静态数据成员(14.5.1.3),类模板的成员函数(14.5.1.1),或者在程序中未指定某些模板参数(14.7,14.5.5)的模板特化,前提是每个模板定义出现在不同的翻译单元中
该子句指出,只要在代码中未指定至少一个模板参数,就可以对同一模板函数进行多个定义.这是为了允许决定参数化函数是否应该在仅在本地信息上进行的模块中实例化.