问题
I have several template classes Impl
(with some abstract methods) that are partially implemented in CPP files so that I need to explicitly instantiate my templates for the linker to find it, like this:
template class Impl<T0>;
template class Impl<T1>;
template class Impl<T2>;
...
template class Impl<Tx>;
As the number of types Tx
grows, I would like to find a better way than to manually expand these lists of explicit instantiations in all necessary files. I thought I could use variadic templates for this, so I tried the following:
template <template <class> class, class...>
struct type_map;
template <template <class> class BaseT, class... Ts>
struct type_map<BaseT, std::tuple<Ts...>> {
using type = std::tuple<BaseT<Ts>...>;
};
typedef std::tuple<T0, T1, T2> MyTypes;
And in the CPP file:
template class type_map<Impl, MyTypes>;
However, this didn't instantiate the templates as I intended (the linker complained about the missing symbols).
Is there a way to make this approach work (i.e. instantiate the template without instantiating an object of it) or a totally different approach that could solve my problem in this situation?
回答1:
I don't think you can do this with variadic templates, but you can do it with the preprocessor.
I see two options. One would be to use Boost.Preprocessor:
// Definitions:
#define ARGUMENTS (T0)(T1)(T2)(T3)(Tx)
#define INSTANTIATE(maUnused, maTemplate, maType) \
template class maTemplate<maType>;
// Usage:
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl, ARGUMENTS)
BOOST_PP_SEQ_FOR_EACH(INSTANTIATE, Impl2, ARGUMENTS)
Another option would be to use the X macro trick:
x.hpp
X(T0)
X(T1)
X(T2)
X(T3)
X(Tx)
#undef X
using_file.cpp
#define X(maType) template class Impl<maType>;
#include "x.hpp"
#define X(maType) template class Impl2<maType>;
#include "x.hpp"
来源:https://stackoverflow.com/questions/23628177/explicit-template-instantiation-with-variadic-templates