类方法的显式特化 - 已定义的符号

xto*_*ofl 7 c++ templates linker-errors one-definition-rule explicit-specialization

One Definition Rule规定程序应包含每个非内联函数的一个定义.对于模板类的成员,这对我来说并不完全清楚:

 ///////////
 // Tfoo.h
 template<typename T> class A { 
     void foo(){} 
 };

 ///////////
 // intfoo.h
 #include <Tfoo.h>
 template<> class Foo<int> { 
     void foo(); // declaration only
 }; 
 /*inline*/ void Foo<int>::foo(){} // definition

 ///////////
 // X.cpp
 #include <intfoo.h>

 ///////////
 // Y.cpp
 #include <intfoo.h>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,clientX.obj和clientY.obj都有一个定义Foo<int>::foo.链接器抱怨此符号定义不止一次:

Y.obj : error LNK2005: "private: void __thiscall Foo<int>::foo(void)" 
(?foo@?$Foo@H@@AAEXXZ) already defined in X.obj
Run Code Online (Sandbox Code Playgroud)

当我在前面inline定义时Foo<int>::foo(),一切顺利,链接器很高兴.当我在单独的编译单元中定义它们时(例如intfoo.cpp).

(注意:此解决方案在/sf/answers/103725751/中提出)

可能是一种误解,但模板类的成员函数总是"内联"?这里的规则是什么?

And*_*owl 11

类模板的显式特化的成员函数就像非模板类的成员函数.毕竟,显式特化一个不依赖于任何模板参数的具体类.

如果将其定义放在多个转换单元包含的头文件中,则编译器将在处理每个转换单元时生成该函数的对象代码.

最终,链接器会抱怨多个定义的符号.该inline关键词阻止这种行为,就像它用于常规非模板函数和非模板类的普通成员函数.

  • “一个明确的专业是一个具体的课程”:这就是我一直在寻找的东西。谢谢。 (2认同)