c++ - 静态库中带有外部模板的 undefined symbol

标签 c++ templates extern c++14

据我所知,存在新的 extern 模板功能以加快编译和链接时间。我正在尝试在(静态)库中使用它,据我所知它应该可以工作,因为 Bjarne Stroustrup's C++11 FAQ明确提及图书馆。

我有一个头文件,其中包含一些内容

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

extern template class Foo<int>;

和一个实现文件

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

这些用于构建静态库libfoo,然后链接到相应的单元测试FooTest。然后,对于在测试中调用 Foo 对象的每个方法,链接都会给我 undefined symbol 错误。

我在这里做什么/做错了什么?

最佳答案

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

失败时Foo.cpp.o不包含 qux::Foo<int, 2ul>::Foo(int const&) 的定义

$ 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 中定义了该符号

$ 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&)

我不确定是什么问题,可能是 Clang 的一个错误,现在已经修复了,但奇怪的是 GCC 也有同样的错误。

导致问题的函数使用了 C++14 的宽松 constexpr 规则(在 constexpr 函数中循环),因此我认为这是编译器在实现该新功能时的错误。

关于c++ - 静态库中带有外部模板的 undefined symbol ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27425943/

相关文章:

c++ - 为什么不能推导嵌套在模板类中的枚举的模板参数?

c - 具有分层控制的函数指针使用: xtern/namespace C++

c++ - 程序以信号 25 终止,超出文件大小限制;为什么?

c++ - 将 DLL 链接到 DLL

c++ - 使用 `const&` 调用模板?

c++ - 使用 int*& 通过引用传递指针会导致奇怪的问题

c++ - 有什么方法可以使模板函数应用于 C++ 中任意长度的数组?

string - 在模板字符串中求值

c++ - 为什么const int需要extern而不是const char *

c - 如何以及在何处调用外部定义的结构