【问题标题】:Explicit template instantiation with variadic templates使用可变参数模板的显式模板实例化
【发布时间】:2014-06-30 22:41:51
【问题描述】:

我有几个模板类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>;

但是,这并没有按照我的预期实例化模板(链接器抱怨缺少符号)。

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

【问题讨论】:

  • 您是否尝试创建 dll?也许您必须将导出宏添加到您的 type_map 类型
  • @Angew 我有几个类可以这样工作,这就是我的问题的原因。我试着把我的问题表述得更清楚一点。
  • @vlad_tepesch 不,我不使用 DLL。这仅与编译器没有生成其他编译单元所需的模板实例的问题有关。
  • 一种可能的解决方案是使用宏。尝试使用BOOST_PP_SEQ_FOR_EACHBOOST_PP_LIST_FOR_EACH

标签: c++ templates c++11 variadic-templates


【解决方案1】:

我认为你不能用可变参数模板做到这一点,但你可以用预处理器做到这一点。

我看到两个选项。一种是使用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"

【讨论】:

  • 不幸的是,我认为在这种情况下没有其他方法。如果我的类不是抽象的,我只能使用可变参数模板方法。还是谢谢!
猜你喜欢
  • 2014-09-13
  • 2014-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
相关资源
最近更新 更多