我有几个模板类Impl
(带有一些抽象方法),它们部分在CPP文件中实现,因此我需要显式实例化我的模板以供链接器找到它,如下所示:
template class Impl<T0>;
template class Impl<T1>;
template class Impl<T2>;
...
template class Impl<Tx>;
随着类型Tx
的增长,我想找到一种比在所有必需文件中手动扩展这些显式实例化列表更好的方法。我以为我可以使用可变参数模板,所以我尝试了以下内容:
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;
在CPP文件中:
template class type_map<Impl, MyTypes>;
但是,这并没有像我预期的那样实例化模板(链接器抱怨丢失的符号)。
有没有办法让这种方法起作用(即实例化模板而不实例化它的对象)或一种完全不同的方法可以解决我在这种情况下的问题?
答案 0 :(得分:2)
我不认为您可以使用可变参数模板执行此操作,但您可以使用预处理器执行此操作。
我看到两个选项。一种是使用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)
另一种选择是使用X macro技巧:
<强> 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"