据我所知,新的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对象的每个方法提供了未定义的符号错误。
我在做什么/出错?
答案 0 :(得分:6)
使用你的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函数中循环),所以我认为这是编译器实现该新特性的一个错误。