为什么函数模板可以存在于多个源文件中 [duplicate]

Why function template can exist in multiple source files [duplicate]

提问人:MinLinC 提问时间:9/3/2023 更新时间:9/3/2023 访问量:50

问:

我知道一个定义规则,以及为什么如果您想在多个源文件中使用它,则不应将函数定义放在头文件中。

但是,我不太明白为什么我们可以将函数模板放在头文件中。在编译期间,编译器会创建一个实例化。现在,每个翻译单元的“int sum(int, int)”是否仍然有两个函数定义,如下例所示。

// main.cpp
include "helper.hpp"

int main() {
    sum(2, 3);
    return 0;
}

// helper.hpp
template <typename T>
T sum(T a, T b) {
    return a + b;
}

// helper.cpp
#include "helper.hpp"

int sum2(int a, int b)
{
    return sum(a, b);
}
C++ 函数 模板 one-definition-rule

评论

0赞 StoryTeller - Unslander Monica 9/3/2023
可悲的是,一个定义规则并不像您在开头的段落中提出的那么简单(仅适用于非内联函数)。它涉及更多,还处理内联函数/变量、类型和模板。可以说,该规则还涉及不同 TU 中的“相同”定义。
0赞 Jan Schultke 9/3/2023
注意:链接为重复的答案不是专门针对函数模板的,但 ODR 的相同豁免通常适用。

答:

-2赞 6502 9/3/2023 #1

只是因为标准是这么说的。

否则,模板实际上将不可用,因此它们可以以这种方式工作(例如,如果在模板体实现中使用变量,则每个实例化必须只有一个静态变量(例如,一个用于,一个单独的用于)。staticintfloat

C++ 是一堆奇怪的规则:例如,如果不先看到一个函数的原型,你就无法调用它......除了在类中,您可以调用方法,即使它们在类的后面定义。为什么会这样?只是因为标准是这么说的。

不要试图过分研究逻辑原因,没有。 只要学习规则......不要过多地猜测,直觉在C++中不是一个好的指南。

评论

0赞 Jan Schultke 9/3/2023
“仅仅因为标准是这样说的”和“只要学习规则”和“C++是一堆奇怪的规则”并不能真正回答这个问题。它只是隐约暗示了一个可能的答案。
0赞 6502 9/3/2023
@JanSchultke:我认为唯一正确的答案是我在第一行写的。你可以尝试合理化它,或者因为编译模型而解释它,但这并不能使它合乎逻辑。这在C++中经常发生:例如,几年前本地类不能用于实例化模板,没有理由......现在他们可以了(感谢上帝);但是他们不能有内联好友方法......(?)仍然没有理由,可能是将来会取消的限制,可能不是。我们只需要等待下一个标准。逻辑在C++中不是一个强大的参与者。
1赞 Jan Schultke 9/3/2023
如果“标准是这样说的”是一个合理的答案,那么你可以提供相关措辞的引用,你可以提供为什么存在这种措辞的理由。这将是一个很好的答案。
0赞 6502 9/3/2023
@JanSchultke:然后查一下,写出来。在我看来,OP 似乎完全理解规则并询问为什么。而且(正如C++经常发生的那样)没有真正的原因......至多有借口;这就是我的答案。如果你过多地关注逻辑,你的C++生活就不会快乐和富有成效。没有错误和警告的编译有意义吗?不。。。但就是这样,你最好知道。std::string s; s=3.14159265359;