如果将extern模板类仅使用一个翻译单元,为什么没有链接错误?

用户名

考虑以下代码:

#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 = intmain因为实际上没有实例化,所以这将导致链接时错误。

为什么此代码链接?

阿斯切普勒

如评论中所述,链接器错误存在,-O0但消失了-O2当您有一个显式的实例化声明时,编译器将假定两者都处于最佳状态:该定义可用,因此,如果编译器感觉像是对其进行内联,则可以。但是,如果编译器不想内联它,则可以假定实际函数将在另一个翻译单元中生成。因此,只有在编译器决定不内联函数时,才可以看到显式实例化它的诺言。

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么可以将单元分配给一个元组而没有编译错误?

为什么C ++的<vector>模板化类没有违反一个定义规则?

为什么仅单击一个链接时所有链接都会更改颜色?

为什么我有一个错误,但没有一个例外?

为什么std :: plus是一个类模板?

有没有办法将两个或多个不同的类链接到一个类中(然后在向量上使用)?

当只有一个实现类时,为什么要使用一个接口?

为什么在模板函数中使用iterator_traits而不是仅使用另一个模板类型参数?

如果没有给出路径,为什么find会打印一个前导“ ./”?

为什么我可以将一个Int分配给一个没有编译器错误的字符串?

C++ 为什么模板化一个类会解决未定义的类错误

Lotus Notes 8.5有重做功能吗?如果没有,为什么没有一个?

为什么没有java.lang.Array类?如果java数组是一个Object,它不应该扩展Object吗?

为什么会出现“类必须具有一个(只有一个)构造函数”错误?

您为什么要一个没有声明公共类的Java文件?

为什么继承一个抽象类,当执行结果没有达到预期

为什么我的 kivy 程序没有从另一个类调用该函数?

仅使用一个静态方法(没有构造函数)初始化类

为什么url_for()将“ static”作为第一个参数使用?没有static()

在春季启动中,为什么我没有将服务类的返回值返回给另一个服务类

如果没有可用的公共接口,则使用一个类的两种实现的模式

仅使用一个类定义重载模板化类模板参数

为什么valgrind说如果我使用2个整数,则只有一个alloc?

如果实际上我没有任何重复的外键,为什么 MySQL 会给我一个重复的外键约束名称错误 (1826)?

为什么在执行完一个函数后进程没有任何错误就结束了?

为什么仅针对一个参数,可变参数模板与非可变模板不同?

如果没有第一个使用JMESPath的JSON密钥,最好的方法是什么?

为什么要抛出一个异常,并使用输入()的时候有没有UnboundLocalError?

如果有一个if-constexpr,那为什么没有switch-constexpr?