为什么我需要模板的C++链接?

use*_*710 0 c c++ extern c++11

有时候我会尝试遵循一些规则的逻辑,有时候为什么事情发生的逻辑会违反我所知道的任何法律.

通常,模板被描述为仅在编译阶段存在的东西,它完全等同于foo为任何给定类型手写一些函数T.

那么,为什么这个代码不编译(我使用C++ 11 gccclang的时刻,但我不认为这是在这种情况下相关的)?

#include <iostream>
#include <cstdint>
#include <cstdlib>
extern "C" {
template <typename T>
T foo(T t)
{
    return t;
}
}
int main()
{
    uint32_t a = 42;
    std::cout << foo(a) << '\n';
    return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)

击败所有逻辑的事情是抱怨是关于链接,而隐含的消息是这个代码不生成函数,它生成其他东西,在编译后它不适合C风格的链接.

这段代码无法编译的技术原因是什么?

Bil*_*nch 14

让我们从一个简单的角度来看待这个问题.至少,使用extern "C"将删除C++名称mangling.那么,我们然后有你的模板,我们将实例化它两次.

int foo(int val);
float foo(float val);
Run Code Online (Sandbox Code Playgroud)

根据C的命名规则,foo从链接器的角度来看,这些规则必须具有相同的名称.如果他们有相同的名字,我们无法区分他们,我们会有一个错误.

在C++下,名称被破坏的规则是实现定义的.因此,C++编译器将对这两个函数应用名称修改来区分它们.也许我们会打电话给他们foo_int,并foo_float.

因为C++可以做到这一点,所以我们没有问题.但是extern "C"要求编译器应用C命名规则.

  • @ user2485710您希望如何从C调用实例化?如果你不打算这样做,那你为什么要使用`extern"C"`? (3认同)
  • @ user2485710:由于你的言论,我变得有点困惑.你能告诉我你认为"extern"C"`的意思吗? (2认同)