在静态库中使用extern模板定义未定义的符号 [英] Undefined symbols with extern templates in a static library
问题描述
据我所知,新的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屋!