How does the compilation of templates work?(模板的编译是如何工作的?)
问题描述
我正在阅读一本关于模板如何工作的书,我无法理解有关模板的说明。
上面写着
当编译器看到模板定义时,它不会生成代码。它仅在我们实例化模板的特定实例时生成代码。只有在使用模板时(而不是在定义模板时)才会生成代码,这一事实会影响我们如何组织源代码以及在检测到错误时……要生成实例化,编译器需要具有定义函数模板或类模板成员函数的代码。因此,与非模板代码不同,模板的标头通常包括定义和声明。
生成代码到底是什么意思?我不明白编译函数模板或类模板与常规函数或类有什么不同。
推荐答案
编译器为模板类实例化中给定的特定类型生成代码。
如果您将模板类声明为
template<typename T>
class Foo
{
public:
T& bar()
{
return subject;
}
private:
T subject;
};
例如,一旦您有了以下实例化
Foo<int> fooInt;
Foo<double> fooDouble;
这些将有效地生成与您定义的类相同的可链接代码
class FooInt
{
public:
int& bar()
{
return subject;
}
private:
int subject;
}
和
class FooDouble
{
public:
double& bar()
{
return subject;
}
private:
double subject;
}
并实例化变量,如
FooInt fooInt;
FooDouble fooDouble;
关于模板definitions(不要与declarations混淆,不管是什么模板)需要与头文件(包括)一起看到这一点,原因非常清楚:
如果没有看到definition,编译器无法生成此代码。但它可以引用最先出现在链接阶段的匹配实例化。
非模板成员函数具有什么使其能够 在标头外部定义,而模板函数不定义 有吗?
非模板类/成员/函数的声明为链接器提供了预定义的入口点。该定义可以从编译的目标文件(==.cpp==compilation unit)中看到的单个实现中提取。 相反,模板化类/成员/函数的声明可以从给定相同或不同模板参数的任意编译单元实例化。这些模板参数的定义需要至少查看一次。它可以是通用的,也可以是专用的。
请注意,您可以为特定类型专门化模板实现(包括在标题中或在特定的compilation unit中)。 如果您希望在compilation units之一中为模板类提供专门化,并且不将模板类与专门化以外的类型一起使用,那么这也足以将它们链接在一起。我希望此示例有助于澄清编译器所做的努力和区别。
这篇关于模板的编译是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:模板的编译是如何工作的?
基础教程推荐
- CString 到 char* 2021-01-01
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 初始化列表*参数*评估顺序 2021-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
