在静态库中使用extern模板定义未定义的符号 [英] Undefined symbols with extern templates in a static library

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

问题描述

据我所知,新的extern模板功能可以加快编译和链接时间。我试图使用这个(静态)库,据我所知应该工作,因为 Bjarne Stroustrup的C ++ 11常见问题解答明确提到了库。

As far as I know the new extern template functionality exists to speed up compile and link times. I am trying to use this in a (static) library, which as far as I know should work, since Bjarne Stroustrup's C++11 FAQ explicitly mentions libraries.

我有一个头文件, p>

What I have is a header file containing something along the lines of

template <typename T>
class Foo {
  // Definitions of the methods
};

extern template class Foo<int>;

和一个实现文件

#include "Foo.hpp"
template class Foo<int>;

这些用于构建一个静态库 libfoo ,然后链接到相应的单元测试 FooTest

These are used to build a static library libfoo, which is then linked to the corresponding unit test FooTest. The linking then gives me undefined symbol errors for every method called on Foo objects in the test.

我在这里做什么/得到错误?

What am I doing/getting wrong here?

推荐答案

使用github代码我可以用GCC 5.0或Clang 3.4重现它,但不是Clang 3.6(从svn构建)。

Using your github code I can reproduce it with GCC 5.0 or Clang 3.4 but not Clang 3.6 (built from svn).

当它失败 Foo.cpp.o 不包含的定义qux :: Foo

$ nm -C Foo.cpp.o 
                 U qux::Foo<int, 2ul>::Foo(int const&)
0000000000000000 W qux::Foo<int, 2ul>::Foo()
                 U qux::Foo<int, 2ul>::Foo(int const&)
0000000000000000 W qux::Foo<int, 2ul>::Foo()
0000000000000000 W qux::Foo<int, 2ul>::operator[](unsigned long) const
0000000000000000 W std::array<int, 2ul>::operator[](unsigned long) const
0000000000000000 W std::__array_traits<int, 2ul>::_S_ref(int const (&) [2], unsigned long)

但是使用Clang 3.6在

But using Clang 3.6 that symbol is defined in

$ nm -C Foo.cpp.o 
0000000000000000 W qux::Foo<int, 2ul>::Foo(int const&)
0000000000000000 W qux::Foo<int, 2ul>::Foo()
0000000000000000 W qux::Foo<int, 2ul>::Foo(int const&)
0000000000000000 W qux::Foo<int, 2ul>::Foo()
0000000000000000 n qux::Foo<int, 2ul>::Foo(int const&)
0000000000000000 n qux::Foo<int, 2ul>::Foo()
0000000000000000 W qux::Foo<int, 2ul>::operator[](unsigned long) const
0000000000000000 W std::array<int, 2ul>::operator[](unsigned long) const
0000000000000000 W std::__array_traits<int, 2ul>::_S_ref(int const (&) [2], unsigned long)
0000000000000000 W std::array<int, 2ul>::end()
0000000000000000 W std::array<int, 2ul>::data()
0000000000000000 W std::array<int, 2ul>::begin()
0000000000000000 W int* std::__addressof<int>(int&)

我不知道是什么问题,它可能是一个bug,现在已经修复,但很奇怪,GCC有相同的bug。

I'm not sure what the problem is, it might be a bug in Clang which has now been fixed, but it's strange that GCC has the same bug.

导致问题的函数使用C ++ 14的松散constexpr规则(在constexpr函数中循环),所以我认为这是编译器实现这个新特性的一个bug。

The function that causes the problem uses C++14's relaxed constexpr rules (looping in a constexpr function), so I assume it's a bug in the compilers' implementation of that new feature.

这篇关于在静态库中使用extern模板定义未定义的符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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