【问题标题】:extern template does not work for gcc?外部模板不适用于 gcc?
【发布时间】:2014-05-13 13:55:02
【问题描述】:

C++11 引入了一个名为“extern template”的功能,表示模板实例存在于其他翻译单元中。(我说的对吗?)

这个(http://www.youtube.com/watch?v=3annCCTx35o) 讲座还告诉你,如果你指定外部模板并且不包括实例化,链接器会产生错误。(视频中大约 2:25)

所以,我尝试构建下一个代码:

#include <iostream>

template<class T>
struct Foo
{
    static constexpr int type_size = sizeof(T);
};

extern template struct Foo<int>;

int main()
{
   std::cout<< Foo<int>::type_size << std::endl;
   return 0;
}

我预计构建会失败,因为该文件不包含显式实例化或专门化,但 gcc 只是构建它,结果运行良好。

我错过了什么?或者,我是不是误会了什么?或者说,gcc 不支持 extern 模板吗?

更新

我尝试了一个非内联函数的类,外部模板按预期工作!

#include <iostream>

template<class T>
struct Foo
{
    static void print(T t);
};

template<class T>
void Foo<T>::print(T t) { std::cout << t << std::endl; }

extern template struct Foo<int>;

// template struct Foo<int>;

int main()
{
   Foo<int>::print(1);
   return 0;
}

如果没有注释行,以上源代码不会生成。 谢谢大家!

【问题讨论】:

  • 无法理解您的问题...问题是什么?
  • 尝试向Foo 添加(非内联!)函数,看看会发生什么。
  • 我的印象是 GCC 家伙是第一个做extern template 的人,在新的 C++ 标准整合之前,它在旧版本的 g++ 中可用。所以这里可能不是编译器的错!
  • @staticx 问题已解决。感谢您的关注。
  • 为了完整起见:当您提出“功能 X 不适用于编译器 Y”形式的问题时,您应该提及您使用的是哪个版本的编译器。在这种情况下,这不是问题,但在很多情况下,答案是“在编译器 Y 版本 nnnn 中添加了功能 X”

标签: c++ templates gcc c++11 extern


【解决方案1】:

如果你指定外部模板并且不包含实例化,链接器会产生错误。

不,不一定。只有当您真正使用该模板时才会出现问题。您正在使用定义为该模板的静态成员的编译时常量,但在编译时将其替换为常量的值。并且在替换之后,模板就不再使用了,所以也就不需要定义模板了。

【讨论】:

  • 在 main 中添加 Foo&lt;int&gt; foo; 仍然可以编译。
  • @PeterSchneider 是的,但这也没有使用在编译时不能直接使用的模板的任何部分。 (特别是它不调用任何构造函数或析构函数,因为Foo的构造函数和析构函数是微不足道的。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多