繁体   English   中英

双模板参数包

[英]double template parameter pack

这是我的 class 的样子:

template<typename ...events_t, std::uint32_t ...stackDepth>
class Module {
    protected: std::tuple<EventHandler<events_t, stackDepth>...> evtHandlers;
    public: Module(std::tuple<EventHandler<events_t, stackDepth>...> _evtHandlers) : 
         evtHandlers{_evtHandlers}{ /* ... */ }
    // ...
}

我必须给EventHandler一对模板 arguments,一个是已处理的事件类型,另一个是用于任务堆栈深度的std::uint32_t

双模板参数包无法按原样编译,但我找不到可以做到的技巧。 有没有办法让这项工作干净利落?

对于模板类/结构,模板可变参数必须位于模板参数列表的末尾。 所以,直接,你只能使用一个。

但是您可以使用例如std::tuple来包装一个(或两个)可变参数包,用于类型,以及std::integer_sequence用于 integer 值。

不幸的是,您必须使用模板专业化:您必须声明主模板接收,例如,几个类型

template <typename, typename>
class Module;

以及使用单一类型名作为模板包装器的特化,如下所示

template <typename ... event_t, std::uint32_t ... stackDepth>
class Module<std::tuple<event_t...>, 
             std::integer_sequence<std::uint32_t, stackDepth...>>
 {
   // ...
 };

鉴于您可以在末尾放置一个可变参数列表,您可以避免使用第二个包装器,因此,例如,

template <typename, std::uint32_t...>
class Module;

template <typename ... event_t, std::uint32_t ... stackDepth>
class Module<std::tuple<event_t...>, stackDepth...>>
 {
   // ...
 };

鉴于此,如果我理解正确,类型( event_t )和数字( stackDepth )是相关的,并且您有一个模板类/结构,它接受单个类型和单个数字作为模板参数( Event_Handler ),我想您可以直接使用Event_Handler作为可变参数。

我的意思如下(完整编译示例)

#include <cstdint>

template <typename, std::uint32_t>
struct Event_Handler
 { };

template <typename...>
class Module;

template <typename ... event_t, std::uint32_t ... stackDepth>
class Module <Event_Handler<event_t, stackDepth>...>
 {
   // ...
 };

int main ()
 {
   Module<Event_Handler<int, 0u>, Event_Handler<long, 1u>>  m;
 }

- 编辑 -

OP问

实际上我不想把它当作一个纯模板参数,而是作为构造函数中的一个实例。 这个技巧有可能吗?

如果我理解正确,您正在寻找“模板推导指南”,从 C++17 开始可用(并且您标记了 C++17,所以应该适合您。

以下是完整的 (C++17) 编译示例; “显式演绎指南”是紧接在main()之前的构造

#include <cstdint>

template <typename, std::uint32_t>
struct Event_Handler
 { };

template <typename...>
class Module;

template <typename ... event_t, std::uint32_t ... stackDepth>
class Module <Event_Handler<event_t, stackDepth>...>
 {
   public: 
      Module (Event_Handler<event_t, stackDepth>...)
       { }
 };

// explicit deduction guide
template <typename ... event_t, std::uint32_t ... stackDepth>
Module (Event_Handler<event_t, stackDepth>...)
   -> Module<Event_Handler<event_t, stackDepth>...>;

int main ()
 {
   Module  m(Event_Handler<int, 0u>{}, Event_Handler<long, 1u>{});
 }

无法显式提供两个列表,但您可以使用特化来捕获它们:

template<typename A, typename B> class C;
template<typename ...As, typename ...Bs>
class C<std::tuple<As...>, std::tuple<Bs...>>
{
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM