Pretty sure I know the answer to this already, but it's worth a shot.
So, say I have a typelist:
template <typename ...Ts>
struct typelist{};
That contains some objects:
struct foo{};
struct bar{};
struct quux{};
using objects = typelist<foo, bar, quux>;
Now I have a templated class (baz
) that can take any of these objects. But, due to codebase size and compilation times, I want to have the implementation of my templated method in a cpp file.
So at the bottom of baz.cpp I have:
template <> class baz<foo>;
template <> class baz<bar>;
template <> class baz<quux>;
The problem is I have lots of classes like baz
, and the list of objects that they work with is also ever changing. So... is there anyway I can keep my single typelist of objects and use that in the cpp file of each baz
-like object to specialize? Then, all I have to do is update my typelist when I have a new object and all the object files will rebuild.
The template <> class baz<foo>;
line forward-declares a specialization and not a template instantiation, which, I assume, is what you want.
I don't think there's a direct way to do this, you'll have to do some metaprogramming. You can use Boost.Preprocessor to generate all the needed code:
#define TYPES (foo)(bar)(quux)
using objects = typelist< BOOST_PP_SEQ_ENUM(TYPES) >;
// Generate extern template declarations in the header
#define EXTERN_TEMPLATE_BAZ(r, data, arg)\
extern template class baz< arg >;
BOOST_PP_SEQ_FOR_EACH(EXTERN_TEMPLATE_BAZ, _, TYPES)
// Generate template instantiations in the .cpp
#define TEMPLATE_BAZ(r, data, arg)\
template class baz< arg >;
BOOST_PP_SEQ_FOR_EACH(TEMPLATE_BAZ, _, TYPES)
There may be a way to do this without preprocessor but doing this would impose additional requirements on the baz
type. The point is to use the type in a context where it has to be instantiated, including all its methods.