如何使用extern模板

Nic*_*las 24 c++ templates visual-studio-2008 explicit-instantiation c++11

我一直在查看C++ 0x的N3291工作草案.我对extern模板感到好奇.第14.7.3节规定:

除了内联函数和类模板特化之外,显式实例化声明具有抑制它们引用的实体的隐式实例化的效果.

仅供参考:"明确的实例化声明"一词是标准的extern template.这已在第14.7.2节中定义.

这听起来像是在说如果你使用extern template std::vector<int>,那么做任何通常隐式实例化的事情std::vector<int>都不会这样做.

下一段更有趣:

如果实体是同一翻译单元中的显式实例化声明和显式实例化定义的主题,则该定义应遵循声明.作为显式实例化声明的主体并且以在否则将导致翻译单元中的隐式实例化(14.7.1)的方式中使用的实体应该是程序中某处的显式实例化定义的主题; 否则该程序格式错误,无需诊断.

仅供参考:术语"显式实例化定义"是这些事物的标准说法:template std::vector<int>.也就是说,没有了extern.

对我来说,这两件事说extern template防止了隐式实例化,但它并没有阻止显式实例化.所以,如果你这样做:

extern template std::vector<int>;
template std::vector<int>;
Run Code Online (Sandbox Code Playgroud)

第二行有效地否定了第一行,明确地做了第​​一行隐含发生的事情.

问题是:Visual Studio 2008似乎不同意.我想要使​​用的方法extern template是阻止用户隐式实例化某些常用模板,以便我可以在.cpp文件中显式实例化它们以减少编译时间.模板只会实例化一次.

问题是我必须在VS2008中围绕它们#ifdef.因为如果单个翻译单元看到extern和非extern版本,它将使extern版本获胜并且没有人会实例化它.然后是链接器错误.

所以,我的问题是:

  1. 根据C++ 0x,正确的行为是什么?应该extern template防止明确的实例化吗?
  2. 如果上一个问题的答案是它不应该,那么VS2008是错误的(被授予,它在规范之前写得很好,所以它不像是他们的错).VS2010如何处理这个问题?它是否实现了正确的extern template行为?

Joh*_*itb 7

它说

除了...类模板专业化

所以它不适std::vector<int>用于它的成员(不是内联成员函数的成员,也可能不是嵌套类.不幸的是,没有一个术语可以同时捕获"类模板专业化和成员专业化"类模板的类".所以有些地方只使用前者,但意味着也包括后者).因此,如果需要std::vector<int>,它的嵌套类(std::vector<int>::iterator如果它被定义为嵌套类)仍将被隐式实例化.

  • 14.7.2,第5段规定:"如果在声明该模板的显式特化之后出现模板的显式实例化,则显式实例化无效." 这似乎是在讨论用户何时编写专业化(而不是生成的专业化).它表示忽略显式特化的显式实例化定义,因为存在显式特化. (3认同)