Nar*_*rek 2 c++ linker templates c++11
如果我会写这样的东西:
// A.h
#ifndef A_h
#define A_h
class A
{
public:
void f();
};
void A::f()
{
}
#endif //A_h
// B.cpp
#include "A.h"
void foo()
{
A a;
a.f();
}
// C.cpp
#include "A.h"
void bar()
{
A b;
b.f();
}
// main.cpp
#include "B.cpp"
#include "C.cpp"
using namespace std;
int main()
{
foo();
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我这样得到一个链接器错误:
错误LNK2005:已在B.obj中定义的"public:void __thiscall A :: f(void)"(?f @ A @@ QAEXXZ)
当A类是类模板时,为什么不会发生同样的问题?最终它在编译期间变成了普通类(非模板类),对吧?出于这个原因,我期望与非模板类相同的行为,即链接器错误.
这里有两个独立的效果:
脱节的成员函数定义是正常的函数定义,并且通过一个定义规则(ODR),它必须在链接中恰好出现一次.内联定义的成员函数是隐式的inline,ODR允许重复内联函数定义:
也就是说,可以将以下代码放在标题中并重复包含它:
struct Foo {
void bar() {} // "inline" implied
};
Run Code Online (Sandbox Code Playgroud)
但如果您的定义不符合规定,则必须在单个翻译单元中.
功能模板可以重复定义,即使它们不是内联的.模板机制通常需要处理模板的重复实例化,以及链接时的重复数据删除.
类模板的成员函数本身就是函数模板,因此无论是否声明它们都无关紧要inline.