考虑以下代码:
#include <iostream>
template<typename T>
class X
{
public:
T t;
void func1() { std::cout << "Test"; }
void func2(T x) { }
};
extern template class X<int>;
int main()
{
X<int> x;
x.func1();
}
此代码可以正确编译和链接(实时)。
但是,我不明白为什么由于extern template class
声明而导致链接错误。根据cppreference.com(重点是我):
显式实例化声明(一个extern模板)跳过了隐式实例化步骤:否则会导致隐式实例化的代码将改用其他地方提供的显式实例化定义(如果不存在此类实例,则会导致链接错误)。通过在使用该源文件的一个源文件中显式声明一个模板实例化,并在其余文件中显式定义它,可以用于减少编译时间。
据我了解,该extern template class
声明应防止编译器隐式实例化X与T = int
在main
。因为实际上没有实例化,所以这将导致链接时错误。
为什么此代码链接?
如评论中所述,链接器错误存在,-O0
但消失了-O2
。当您有一个显式的实例化声明时,编译器将假定两者都处于最佳状态:该定义可用,因此,如果编译器感觉像是对其进行内联,则可以。但是,如果编译器不想内联它,则可以假定实际函数将在另一个翻译单元中生成。因此,只有在编译器决定不内联函数时,才可以看到显式实例化它的诺言。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句