c – extern模板和不完整类型

最近,当我试图优化我的包含层次结构时,我偶然发现了a.hpp文件:

template<class T>
class A
{
  using t = typename T::a_t;
};

class B;

extern template class A<B>;

这似乎是不正常的.实际上,似乎最后的extern模板语句导致A< B>的实例化.这会导致编译器抱怨不完整的类型.

我的目标是定义A< B>.在a.cpp中:

#include <b.hpp>
template class A<B>;

这样我就不必在a.hpp中包含b.hpp,这似乎是一个减少编译时间的好主意.但它不起作用(a.hpp本身不编译!)有更好的方法吗?

注意:当然我可以不使用显式模板实例化,但这不是我想要的!我想“预编译”A< B>如果使用它,则节省编译时间,但如果A< B>不使用我不想在每个使用a.hpp的文件中包含b.hpp!

最佳答案 从 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1448.pdf起

The extern specifier used to declare an explicit instantiation of a
class template only suppresses explicit instantiations of definitions
of member functions and static data members not previously specialized
in the translation unit containing the declaration.

因此,如果A中需要B的定义,则不能在不知道B的情况下使用extern模板.您当然可以尝试去除该要求.在给定的情况下,您可以删除using t声明并使用meta函数来生成该类型:

template<typename T>
struct get_a_t;

template<typename T>
struct get_a_t<A<T>>
{
   using type = typename T::a_t;
};

不确定它在你的情况下是否可行.一旦A需要存储B或B :: a_t,你需要B.引用和指针就可以了.

点赞