Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extern template & incomplete types

Recently when I was trying to optimize my include hierarchy I stumbled upon the file a.hpp:

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

class B;

extern template class A<B>;

which seems to be ill-formed. In fact it seems as if the extern template statement at the end causes an instantiation of A<B> which causes the compiler to complain about an incomplete type.

My goal would have been to define A<B> in a.cpp:

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

This way I avoid having to include b.hpp from a.hpp which seems like a good idea to reduce compile time. However it does not work (a.hpp on itself doesn't compile!) Is there a better way of doing this?

Note: Of course I could just not use explicit template instantiation but this is not what I want! I would like to "precompile" A<B> to save compilation time if it were used, but if A<B> is not used I don't want to include b.hpp in every file that uses a.hpp!

like image 764
craffael Avatar asked Jan 07 '16 14:01

craffael


1 Answers

The extern template declaration prevents the instantiation of member function bodies, but it forces the instantiation of the class definition, since the compiler needs that anyway, and the class body needs a full definition of the template argument since it accesses its members. I'm afraid that hiding B's body from users of A<B> is not possible.

extern template is an optimization, but it doesn't change the fundamental workings of the instantiation mechanism.

like image 156
Sebastian Redl Avatar answered Sep 30 '22 16:09

Sebastian Redl