c++ - 多文件模板实现

标签 c++ templates

对于普通函数,声明和定义通常像这样在多个文件中分开:

// Foo.h

namespace Foo
{
    void Bar();
}

.

// Foo.cpp

#include "Foo.h"

void Foo::Bar()
{
    cout << "Inside function." << endl;
}

据我了解,这不能使用模板来完成。声明和定义不能分开,因为模板的适当形式是在需要时“按需”创建的。

那么,在像这样的多文件项目中,模板通常是如何定义的以及在哪里定义的?我的直觉是它会在 Foo.cpp 中,因为它通常是函数的“主要内容”所在的位置,但另一方面,它是要包含的头文件。

最佳答案

您需要在 .hxx 文件中编写模板化方法的定义,并将其包含在声明它的头文件 (.hh) 的末尾。 .cc/.cpp 用于定义非模板方法。

因此您将拥有一个 .hh、一个 .hxx(包含在 .hh 的末尾)和一个 .cc;这样包括您的模板化类头文件也将包括它的定义。

例子:

// list.hh
#IFNDEF LIST_HH
# DEFINE LIST_HH

template <typename T>
class List
{
  void fun1(T a);

  void fun2();
}

# include "list.hxx"

#ENDIF

// list.hxx
#IFNDEF LIST_HXX
# DEFINE LIST_HXX

# include "list.hh"

template <typename T>
void List::fun1(T a)
{
   // ...
}

#ENDIF

// list.cc

#include "list.hh"

void List::fun2()
{
   // ...
}


// anywhere.cc

#include "list.hh"

// ...

编辑

有几种编译模板的策略。最常见的策略是上面描述的让类模板的每个用户都实例化代码的策略。

但是,因为 *.hh 文件包含 *.hxx 文件,每次需要模板的简单声明时,完整的实现都会随之而来。如果实现需要其他声明,如 std::string,则强制所有客户端代码解析字符串 header 。

为避免多次实例化(耗费时间和空间),您可以引入第四种文件类型 *.hcc:必须为每个具体模板参数编译一次的文件。

See Also Compile-Time Dependencies

EDIT2

将模板定义直接写在头文件中称为包含模型。这样做会增加包含 header 的成本。不仅因为我们添加了模板的定义,还因为我们包含了代表数千行的标题(,,等等)。 编译重要程序的真正问题(我们在这里谈论的是数小时的编译时间)分离模型

Source

我的最后一个论点是:清除​​头文件,使其只包含类声明及其文档。这样,任何其他程序员都能够快速阅读您的头文件:这个类的公共(public)接口(interface)是什么,文档是怎么说的。

关于c++ - 多文件模板实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4496440/

相关文章:

c++ - char* 和 wchar_t* 的区别

templates - 在哪里可以找到一些好的 UI 模板来设计我的应用程序?

c++ - 固定数量的参数包元素来初始化模板化类

c++ - 类型别名是否用作函数签名的函数参数类型?

c++ - 为什么这段代码可以在 Coliru 上编译,但不能在 Xcode 上编译?

c++ - 两种类型的模板特化

c++ - 重载 'ref(Select::Expressions::Code&)' 的调用在 C++11 中不明确

c++ - OpenGL通用图像读取器和GLFW(glfwReadImage、glfwLoadTexture2D)支持各种图像格式

c++ - 如果遍历路径每次都相同,如何在不使用邻接表的情况下在 C++ 中实现有向图?

Linux 中的 C++ Stream 接口(interface)