我目前正在阅读一本书,它有以下示例:
//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>;
第二个定义然后否定外部?我实在看不懂这个例子。
编辑1:添加注释代码。
编辑2:我几乎可以肯定我的理解是正确的。谢谢你的回答。
在前面的代码块中,我们在a行和B行之间定义了一个类模板,然后从C行到d行,我们实现了它的成员函数foo()因为F行和line之间的代码块G被注释掉了(这意味着没有对应的foo()定义这显式int类型实例化),我们有一个链接错误。为了解决这个问题,我们需要更换#if 0 + #if 1
也许这有助于你理解。
来自c++ 20(13.9.2显式实例化)
2显式实例化的语法为:
explicit-instantiation:
externopt template declaration
有两种形式的显式实例化实例化定义和显式实例化声明。一个显式实例化声明以extern关键字开始。
这一行
extern template struct A < int > ;
是类特化struct A<int>
的显式实例化声明。