如何使用extern模板 [英] How to use extern template

查看:206
本文介绍了如何使用extern模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在通过N3291工作草案C ++ 0x。我很好奇外部模板。第14.7.3节说明:


除了内联函数和类模板的特殊化,显式实例化声明具有抑制隐式实例化


FYI:术语显式实例化声明是标准的 extern template 。这在第14.7.2节中定义。



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

$ b $ / code $ b

下一段更有趣:


如果一个实体同时是一个显式实例化声明和在同一翻译单元中的显式实例化定义,该定义将遵循声明。作为显式实例化声明的主体并且也以将以其他方式导致翻译单元中的隐式实例化(14.7.1)的方式使用的实体将是程序中某处的显式实例化定义的主体;


FYI:术语显式实例化定义是标准的,代表这些东西: template std :: vector< int> 。也就是说,没有 extern



对我来说,这两个东西说 extern template 阻止隐式实例化,但它不会阻止显式实例化。所以,如果你这样做:

  extern template std :: vector< int& 
template std :: vector< int> ;;

第二行通过显式地阻止第一行隐式发生而有效地否定第一行。 p>

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



问题是我必须在VS2008中基本上#ifdef。因为如果单个翻译单元看到 extern 和非 - extern 版本,它将使 extern 版本赢,没有人会实例化它。因此,我的问题是:


  1. 根据C ++ 0x,什么是正确的行为?应该 extern template 阻止显式实例化吗?

  2. 如果上一个问题的答案是不应该,错误(授予,它在规范之前写得很好,所以它不像是它们的错误)。 VS2010如何处理这个?是否实现正确的 extern模板行为?


解决方案

它表示


除了...类模板特化


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


I've been looking through the N3291 working draft of C++0x. And I was curious about extern template. Section 14.7.3 states:

Except for inline functions and class template specializations, explicit instantiation declarations have the effect of suppressing the implicit instantiation of the entity to which they refer.

FYI: the term "explicit instantiation declaration" is standard-speak for extern template. That was defined back in section 14.7.2.

This sounds like it's saying that if you use extern template std::vector<int>, then doing any of the things that would normally implicitly instantiate std::vector<int> will not do so.

The next paragraph is more interesting:

If an entity is the subject of both an explicit instantiation declaration and an explicit instantiation definition in the same translation unit, the definition shall follow the declaration. An entity that is the subject of an explicit instantiation declaration and that is also used in a way that would otherwise cause an implicit instantiation (14.7.1) in the translation unit shall be the subject of an explicit instantiation definition somewhere in the program; otherwise the program is ill-formed, no diagnostic required.

FYI: the term "explicit instantiation definition" is standard speak for these things: template std::vector<int>. That is, without the extern.

To me, these two things say that extern template prevents implicit instantiation, but it does not prevent explicit instantiation. So if you do this:

extern template std::vector<int>;
template std::vector<int>;

The second line effectively negates the first by explicitly doing what the first line prevented from happening implicitly.

The problem is this: Visual Studio 2008 doesn't seem to agree. The way I want to use extern template is to prevent users from implicitly instantiating certain commonly-used templates, so that I can explicitly instantiate them in the .cpp files to cut down on compile time. The templates would only be instantiated once.

The problem is that I have to basically #ifdef around them in VS2008. Because if a single translation unit sees the extern and non-extern version, it will make the extern version win and nobody would ever instantiate it. And then come the linker errors.

So, my questions are:

  1. What is the correct behavior according to C++0x? Should extern template prevent explicit instantiation or not?
  2. If the answer to the previous question is that it should not, then VS2008 is in error (granted, it was written well before the spec, so it's not like it's their fault). How does VS2010 handle this? Does it implement the correct extern template behavior?

解决方案

It says

Except for ...class template specializations

So it does not apply to std::vector<int>, but to its members (members that aren't inline member functions and presumably that aren't nested classes. Unfortunately, there isn't a one term that catches both of "class template specialization and specializations of member classes of class templates". So there are some places that use only the former but mean to also include the latter). So std::vector<int> and its nested classes (like std::vector<int>::iterator, if it is defined as a nested class) will still be implicitly instantiated if needed.

这篇关于如何使用extern模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆