为什么只能在头文件中实现模板?

主ID

引用C ++标准库:教程和手册

目前使用模板的唯一可移植方法是通过使用内联函数在头文件中实现模板。

为什么是这样?

(澄清:头文件不是唯一的可移植解决方案。但是它们是最方便的可移植解决方案。)

卢克·图拉耶

警告:这是没有必要把落实在头文件中,看到这个答案的末尾替代解决方案。

无论如何,您的代码失败的原因是,在实例化模板时,编译器会使用给定的template参数创建一个新类。例如:

template<typename T>
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f; 

阅读此行时,编译器将创建一个新类(我们称之为FooInt),其等效于以下内容:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

因此,编译器需要访问方法的实现,以使用template参数实例化它们(在本例中为int)。如果这些实现不在头文件中,则将无法访问它们,因此编译器将无法实例化模板。

一个常见的解决方案是将模板声明写入头文件中,然后在实现文件中实现该类(例如.tpp),并将此实现文件包括在头文件的末尾。

oo

template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

Foo.tpp

template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}

这样,实现仍与声明分开,但编译器可以访问。

替代解决方案

另一个解决方案是使实现分离,并显式实例化所需的所有模板实例:

oo

// no implementation
template <typename T> struct Foo { ... };

Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float

如果我的解释不够清楚,您可以查看有关此主题C ++ Super-FAQ

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么此模板只能在单个文件中工作,而不能在多个文件中工作?

为什么我只能在扩展中实现Equatable

头文件中模板类实现的模板成员

为什么我不能在头文件中定义全局函数?

为什么我不能在头文件中单独写入名称空间的层次结构?

为什么不能在公共头文件中初始化静态类成员?

为什么不能在Visual Studio中禁用预编译头文件?

为什么C ++模板函数无法识别同一头文件中的函数

为什么我可以在头文件中实现类的成员函数?

为什么在ng-include中通过onLoad传递变量时,变量只能在模板中访问?

为什么要包括头文件而不是实现?

为什么“位置:相对”只能在 Chrome 中工作?

为什么接口只能在顶级类中声明?

函数只能在主线程中调用,为什么?

为什么我的动画只能在预览中工作?

为什么我的网页游戏只能在Chrome中运行?

为什么即使使用#ifndef HEADER_H也不能在头文件中声明和分配全局变量

为什么 G3 连续性只能在两条边之间实现?

头文件中的C ++模板,实现文件* .cc中的错误“错误:预期为类或名称空间”

为什么可以在头文件中定义类?

为什么Eclipse CDT索引不在路径中的头文件?

为什么不建议在头文件中定义宏?

为什么C ++头文件不需要包含实现文件(.cpp)?

为什么头文件有单独的实现文件?(我的教授正确吗?)

为什么不能在包含模板Laravel中翻译?

为什么不能在WindowAdapter中实现某些方法呢?

在C ++中,头文件到底是什么,实现文件中到底是什么?

为什么只能在同一包中定义的类型上声明Go中的方法?

在Objective-C中,头文件和实现文件中的导入有什么区别?