gpt4 book ai didi

c++ - 为什么模板没有重新定义,为什么都写在头文件里了?

转载 作者:搜寻专家 更新时间:2023-10-30 23:54:01 25 4
gpt4 key购买 nike

如果我会这样写:

// 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;
}

我收到这样的链接器错误:

error LNK2005: "public: void __thiscall A::f(void)" (?f@A@@QAEXXZ) already defined in B.obj

为什么当 A 类是类模板时不会发生同样的问题?最终它在编译过程中变成了一个普通类(一个非模板类),对吧?出于这个原因,我期望与非模板类的行为相同,即链接器错误。

最佳答案

这里有两个独立的效果:

  1. 越界的成员函数定义是正常的函数定义,根据一个定义规则 (ODR),它必须在链接中恰好出现一次。内联定义的成员函数是隐式内联,并且 ODR 允许重复内联函数定义:

    也就是把下面的代码放在一个header中,重复包含就可以了:

    struct Foo {
    void bar() {} // "inline" implied
    };

    但如果定义不一致,它必须在单个翻译单元中。

  2. 函数模板可以重复定义,即使它们不是内联的。一般来说,模板机制已经需要处理模板的重复实例化,并在链接时处理重复数据删除。

    类模板的成员函数本身就是函数模板,因此是否将它们声明为内联并不重要。

关于c++ - 为什么模板没有重新定义,为什么都写在头文件里了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36841401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com