使用可变参数模板的显式模板实例化

fsc*_*enm 7 c++ templates variadic-templates c++11

我有几个Impl部分在CPP文件中实现的模板类(带有一些抽象方法),因此我需要显式实例化我的模板以供链接器找到它,如下所示:

template class Impl<T0>;
template class Impl<T1>;
template class Impl<T2>;
...
template class Impl<Tx>;
Run Code Online (Sandbox Code Playgroud)

随着类型数量的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;
Run Code Online (Sandbox Code Playgroud)

并在CPP文件中:

template class type_map<Impl, MyTypes>;
Run Code Online (Sandbox Code Playgroud)

但是,这并没有按照我的意图实例化模板(链接器抱怨丢失的符号).

有没有办法使这种方法工作(即实例化模板而不实例化它的对象)或一种完全不同的方法,可以在这种情况下解决我的问题?

Rei*_*ica 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)
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用X 宏技巧:

x.hpp

X(T0)
X(T1)
X(T2)
X(T3)
X(Tx)

#undef X
Run Code Online (Sandbox Code Playgroud)

使用文件.cpp

#define X(maType) template class Impl<maType>;
#include "x.hpp"

#define X(maType) template class Impl2<maType>;
#include "x.hpp"
Run Code Online (Sandbox Code Playgroud)