【发布时间】:2011-07-17 19:46:33
【问题描述】:
我并不完全清楚新的extern template 功能是如何在 C++11 中工作的。我了解它旨在帮助加快编译时间,并简化与共享库的链接问题。这是否意味着编译器甚至不解析函数体,从而强制进行非内联调用?或者它只是指示编译器在进行非内联调用时不生成实际的方法体?显然,链接时代码生成无法承受。
作为差异可能重要的具体示例,考虑一个对不完整类型进行操作的函数。
//Common header
template<typename T>
void DeleteMe(T* t) {
delete t;
}
struct Incomplete;
extern template void DeleteMe(Incomplete*);
//Implementation file 1
#include common_header
struct Incomplete { };
template void DeleteMe(Incomplete*);
//Implementation file 2
#include common_header
int main() {
Incomplete* p = factory_function_not_shown();
DeleteMe(p);
}
在“实施文件 2”中,将 delete 指向 Incomplete 的指针是不安全的。所以DeleteMe 的内联版本会失败。但是,如果将其保留为实际的函数调用,并且函数本身是在“实现文件 1”中生成的,那么一切都会正常工作。
作为推论,具有类似extern template class 声明的模板类的成员函数的规则是否相同?
出于实验目的,MSVC 会为上述代码生成正确的输出,但如果删除了 extern 行,则会生成有关删除不完整类型的警告。然而,这是他们几年前引入的非标准扩展的残余,所以我不确定我能相信多少这种行为。我无法访问任何其他构建环境来进行实验 [保存 ideone 等人,但在这种情况下,仅限于一个翻译单元是相当有限的]。
【问题讨论】:
-
+1 回答一个我因正确原因而没有完全理解的问题。令人耳目一新。
-
我喜欢这个问题,因为我在现实世界的项目中没有找到这个 C++11 功能的有用和优雅的用例,我希望从讨论中得到启发。