对于普通函数,声明和定义通常在多个文件中分开,如下所示:
// Foo.h
namespace Foo
{
void Bar();
}
.
// Foo.cpp
#include "Foo.h"
void Foo::Bar()
{
cout << "Inside function." << endl;
}
这是我的理解,这不能做的模板。声明和定义不能分开,因为模板的适当形式是在需要时“按需”创建的。
那么,在像这样的多文件项目中,模板通常是如何定义的,定义在哪里?我的直觉是,它应该在Foo.cpp
中,因为这是函数的“肉”通常在哪里,但另一方面,它是将要包含的头文件。
4条答案
按热度按时间amrnrhlw1#
类中编写模板化方法的定义。hxx文件并将其包含在头文件的末尾(.hh)在其中声明。.cc/.cpp用于定义非模板化方法。
所以你会有一个。hh、一个.hxx(包含在.hh)和一个。cc;这样包含模板化的类头文件也会包含它的定义。
示例:
编辑
有几种编译模板的策略。最常见的策略是上面描述的让类模板的每个用户示例化代码的策略。
因为 *。hh文件包含 *。hxx文件,每次需要一个模板的简单声明时,完整的实现都会随之而来。如果实现需要其他声明,如std::string,则强制所有客户端代码解析字符串头。
为了避免多次示例化(消耗时间和空间),可以引入第四种类型的文件 *。hcc:必须为每个具体模板参数编译一次的文件。
See Also Compile-Time Dependencies
EDIT2
直接在头文件中写入模板定义,称为包含模型。这样做会增加包含标头的成本。这不仅是因为我们添加了模板的定义,还因为我们包含了代表数千行的标题(,,whatever)。编译重要程序的真实的问题(我们在这里谈论的是数小时的编译)。分离模型
Source
最后一个论点:请清除头文件,使其仅包含类声明及其文档。像这样,任何其他程序员都可以快速读取你的头文件:这个类的公共接口是什么,文档是怎么说的。
lymgl2op2#
模板代码保留在
.hh
文件中。没有理由将它们分开,尽管将定义放在所有声明之后是一个很好的做法。当编译器生成模板代码时,它会对其进行标记,以便链接器知道一个编译单元中的模板的示例化(即。即
.o
文件)与另一个单元中的代码完全相同。它将保留一个并丢弃其余的,而不是用“多重定义的符号”错误来保释。这对于具有良好模板支持的现代编译器来说是正确的。在GCC的情况下,由于2。8.(我知道,我为gccwww.example写了很多代码 www.example.com 。)
ijxebb2r3#
我很失望,没有答案提到C++标准允许你把定义和声明分开。是这样的:
不幸的是,几乎没有编译器支持 export。科莫就是这样的人。
但是,export 在C0x中从C中删除。
ee7vknir4#
令人惊讶的是,每个人都完全错过了泛型类型的方法。实际上利用唯一的类型占位符。
注意事项
如果你了解链接器/编译器的行为,你需要为这些后果做好准备和计划。
可能是一个好主意,FirstLetter泛化占位符,使它是完全独特的(i。即
template <typename OMT>
和template <typename OLT>
)