好吧,我想我只是因显式模板实例化而非常困惑〜> _<〜
另外,请参阅以下代码:
#include <iostream>
#include <vector>
std::vector<int> a; // Implicit instantiation definition.
// Explicit instantiation declaration.
extern template class std::vector<int>;
int main() {
std::cout << std::vector<int>().size(); // So what?
}
导致链接错误
/tmp/ccQld7ol.o: In function `_GLOBAL__sub_I_a':
main.cpp:(.text.startup+0x6e): undefined reference to `std::vector<int, std::allocator<int> >::~vector()'
collect2: error: ld returned 1 exit status
使用GCC 5.2,但使用clang 3.6构建正常。根据标准哪一个是正确的?
我希望有一种深刻的方式来理解显式模板实例化,以便可以逻辑推断和解释上述所有问题的答案。
答案 0 :(得分:1)
[temp.explicit] / P11:
作为显式实例化声明主题的实体 并且这也以一种否则会导致隐含的方式使用 翻译单元中的实例化(14.7.1)应为 程序中某处的显式实例化定义; 否则程序结构不合理,无需诊断。
答案 1 :(得分:0)
首先,你似乎正在过度思考明确的立场。没什么特别的。它所做的一切,它允许某人使用模板化的函数或类,而无需显示模板定义。它通过创建一个带有指定模板的函数或类的实例来实现,因此它不再是模板而是实际可用的东西。例如,当你有一个模板类,但是想要隐藏你从未提供给用户的.cpp文件中的实际代码时,可以使用它 - 而不是给它们编译的.o文件。要使其工作,您可以使用您认为用户对模板参数所需的类型显式实例化模板。 (当然,这是一种罕见的情况,因为这种类型的集合是这样的)。没有更多的东西了。
同一类型的隐式和显式实例可以共存。隐式实例化将产生弱符号,显式实例将产生“强”符号。强符号覆盖弱符号,并且不会违反ODR。一切都会好的。
至于你的错误,你需要从你的显式实例中删除'extern'。