假设一标题的文件限定了一个功能的模板。现在假设的两个执行情况的文件 #include 这个头,他们每个人都有一个叫功能的模板。在这两种执行文件的功能的模板的实例与相同的类型。

// header.hh
template <typename T>
void f(const T& o)
{
    // ...
}

// impl1.cc
#include "header.hh"

void fimpl1()
{
    f(42);
}

// impl2.cc
#include "header.hh"

void fimpl2()
{
    f(24);
}

一个可预期的接头会抱怨多个定义 f().具体地说,如果 f() 不会是一个模板然后,将确实是这种情况。

  • 怎么连接不抱怨多个定义 f()?
  • 这是标准中规定的接头必须处理这种情况正常?换句话说,我可以永远依靠的程序类似于上述汇编和链路?
  • 如果连接能够聪明足以消除歧义的一套功能的模板的实例,为什么不能做同样的经常职能,给予它们相同的情况一样化功能的模板?
有帮助吗?

解决方案

为了支持C++、连接足够的智慧认识到,他们都是一样的功能和抛出所有,但之一。

编辑:澄清:连接不比较功能的内容,并确定它们是相同的。模板功能的标记和接头认识到,他们有同样的签名。

其他提示

Gnu C++编译器的手册已 一个良好的讨论的这个.一个摘录:

C++模板是第一语言 功能要求更多情报 从环境通常不止一个 现在UNIX系统。不知怎的, 编译器和连接器必须确保 每个模板中的实例发生 正是曾经在执行,如果它 是需要的,而不是在所有其他方式。有两种基本方法来这 问题,这是被称为 Borland模型和Cfront模型。

Borland模型

Borland C++解决的模板 化问题通过加入 代码相当于共用区块来 他们的接头;编译器发出的 模板的情况下在每个翻译 单位,使用它们,以及连接 崩溃他们在一起。优点 这种模式是,只接头 已考虑的对象的文件 自己;没有外部 复杂性的担心。此 缺点是汇编时间 增加是因为该模板码 正在编制多次。代码 写入这个模型趋向于 包括定义的所有模板 在该标题的文件,因为它们必须 看到以实例化。

Cfront模型

AT&T C++翻译,Cfront, 解决该模板的实例 问题通过创建的概念 模板库,一个自动 保持地方的模板 实例保存。一个更现代的 版本的存储库的工作 下:作为个别对象的文件 建,编译器的任何地方 模板的定义和 实例中所遇到的 库。在链接时,链接 包装纸增加了对象 储存库,编制所需的任何 实例,这是以前没有 发射。这种模式的优点 更多的最佳速度和汇编 能够使用该系统的连接;执行Borland模型a 编译器供应商也需要更换 链接器。其缺点是 大幅增加的复杂性,并因此 潜在的错误;对于某些代码 这可能是正透明的,但是 在实践中它可能是非常困难的 建立多个程序中的一个 目录和一个程序在多 目录。代码写的这个 模型趋向于单独的定义 非内联成员的模板进入一个 单独的文件,这应该是 编制分开。

当使用与GNU ld版2.8或 后来一个小精灵的系统,例如 GNU/Linux或Solaris2,或在 Microsoft Windows,G++支持 Borland模型。在其它系统中,G++ 实现既不是自动的模式。

这或多或少是一个特殊的情况下,只是为了模板。

编译器,只生成模板的实例,实际上是使用。因为它没有控制什么代码将产生从其他来源的文件,它的生成模板的代码一旦为每一文件,以确保方法产生的。

由于很难解决这个(标准有一个 extern 关键词的模板,但g++没有实施)连接简单地接受多个定义。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top