[英]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.