我可以从类型列表中声明模板特化吗?

Sam*_*ett 7 c++ templates metaprogramming template-specialization

很确定我已经知道答案,但值得一试.

所以,说我有一个类型列表:

template <typename ...Ts>
struct typelist{};
Run Code Online (Sandbox Code Playgroud)

那包含一些对象:

struct foo{};
struct bar{};
struct quux{};

using objects = typelist<foo, bar, quux>;
Run Code Online (Sandbox Code Playgroud)

现在我有一个模板化的class(baz)可以接受任何这些对象.但是,由于代码库大小和编译时间,我希望在cpp文件中实现我的模板化方法.

所以在baz.cpp的底部,我有:

template <> class baz<foo>;
template <> class baz<bar>;
template <> class baz<quux>;
Run Code Online (Sandbox Code Playgroud)

问题是我有很多类baz,并且他们使用的对象列表也在不断变化.那么......无论如何我可以保留我的单个对象类型列表并在每个baz类似对象的cpp文件中使用它来专门化吗?然后,当我有一个新对象并且所有目标文件将重建时,我所要做的就是更新我的类型列表.

And*_*hev 11

template <> class baz<foo>;行前瞻性声明了一个专业化,而不是一个模板实例,对此,我认为,是你想要的.

我认为没有直接的方法可以做到这一点,你必须做一些元编程.您可以使用Boost.Preprocessor生成所有需要的代码:

#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)
Run Code Online (Sandbox Code Playgroud)

没有预处理器可能有一种方法可以做到这一点,但这样做会对baz类型施加额外的要求.关键是要在必须实例化的上下文中使用该类型,包括其所有方法.

  • 所以?尽管如此,这是一个有效的解决方案. (3认同)
  • 我只是建议我认为最有效的解决方案 - 我已经多次以这种方式解决了类似的任务.如果Boost不可用,则会给出多个其他答案.我让提问者决定什么最适合他. (3认同)