c++ - 显式模板实例化示例
问题描述
我目前正在读一本书,它有以下示例:
//ch4_4_class_template_explicit.cpp
#include <iostream>
using namespace std;
template < typename T > //line A
struct A {
A(T init): val(init) {}
virtual T foo();
T val;
}; //line B
//line C
template < class T > //T in this line is template parameter
T A < T > ::foo() { //the 1st T refers to function return type,
//the T in <> specifies that this function's template
//parameter is also the class template parameter
return val;
} //line D
extern template struct A < int > ; //line E
#if 0 //line F
int A < int > ::foo() {
return val + 1;
}
#endif //line G
int main(void) {
A < double > x(5);
A < int > y(5);
cout << "fD=" << x.foo() << ",fI=" << y.foo() << endl;
return 0; //output: fD=5,fI=6
}
有人可以向我解释一下这条线
extern template struct A < int > ;
确实和为什么第二个定义foo()
?我了解显式模板实例化是什么以及为什么它有时很有用,但extern
我并不清楚它的用途。
本书对这一行有以下解释:
使用 extern 关键字可防止该函数模板的隐式实例化(有关详细信息,请参阅下一节)。
所以extern
阻止我们做以下事情?:
auto obj = A<int>;
然后第二个定义否定 extern? 我真的无法理解这个例子。
编辑 1:添加了注释代码。
编辑2:我几乎可以肯定我的理解是正确的。但感谢您的回答。
书上的解释:
在前面的代码块中,我们在 A 行和 B 行之间定义了一个类模板,然后我们从 C 行到 D 行实现了它的成员函数 foo()。接下来,我们为 int 显式实例化它在 E 行键入。由于 F 行和 G 行之间的代码块被注释掉了(这意味着对于这个显式的 int 类型实例没有 foo() 的相应定义),我们有一个链接错误。为了解决这个问题,我们需要在 F 行用 #if 1 替换 #if 0。
解决方案
也许这可以帮助您理解。
从 C++ 20 (13.9.2 显式实例化)
2 显式实例化的语法是:
explicit-instantiation:
externopt template declaration
显式实例化有两种形式:显式实例化定义和显式实例化声明。显式实例化声明以 extern 关键字开头。
所以这条线
extern template struct A < int > ;
是类专业化的显式实例化声明struct A<int>
。
推荐阅读
- r - Data.table 单线程警告
- c# - VS Code / OmniSharp failing to load project; Can't find a package that is present
- javascript - 如何从文本框中获取输入并使用它在 Google 地图上搜索位置?
- python - 将 numpy 数组扩展到 n*length 并复制其元素的有效方法?
- javascript - Next.js 无法在 HOC 中获取异步数据
- matlab - 平均信号总和
- reactjs - Materializecss 数据长度在反应中不起作用
- c# - 从具有前导自定义变量的字符串中获取括号值
- react-native - 当我在 react-native 中返回上一个屏幕时如何清空数组?
- css - 不同的谷歌字体之王