C++ 双模板参数包
下面是我的班级的样子:C++ 双模板参数包,c++,templates,parameters,c++17,variadic-templates,C++,Templates,Parameters,C++17,Variadic Templates,下面是我的班级的样子: 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, stackDep
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}{ /* ... */ }
// ...
}
模板
类模块{
受保护:std::tuple evthandler;
公共:模块(标准::元组_evthandler):
埃夫坦德勒{{u埃夫坦德勒}{/*…*/}
// ...
}
我必须给EventHandler
一对模板参数,一个是已处理的事件类型,另一个是任务堆栈深度的std::uint32\t
双模板参数包无法按原样编译,但我找不到一个可以做到这一点的技巧。
有什么方法可以使这项工作干净地进行吗?没有办法明确地提供两个列表,但您可以使用专门化来捕获它们:
template<typename A, typename B> class C;
template<typename ...As, typename ...Bs>
class C<std::tuple<As...>, std::tuple<Bs...>>
{
...
}
模板类C;
模板
C类
{
...
}
模板类/结构的模板可变参数必须位于模板参数列表的末尾。因此,直接来说,您只能使用一个
但您可以使用一个(或两个)变量包来包装变量包,例如,对于类型,std::tuple
,对于整数值,std::integer\u sequence
不幸的是,您必须使用模板专门化:您必须声明主模板接收(举例来说)两种类型
template <typename, typename>
class Module;
--编辑--
OP问道
实际上,我不想把它作为一个纯模板参数,而是作为构造函数中的一个实例。这个把戏有可能吗 如果我理解正确,您正在寻找“模板推导指南”,从C++17开始提供(您标记了C++17,因此应该适合您) 下面是一个完整的(C++17)编译示例;“显式推导指南”是紧靠
main()
#包括
模板
结构事件处理程序
{ };
模板
类模块;
模板
类模块
{
公众:
模块(事件处理程序…)
{ }
};
//明确演绎指南
模板
模块(事件处理程序…)
->模块;
int main()
{
模块m(事件处理程序{},事件处理程序{});
}
这允许模板类型推断吗?我想从一个简单的EventHandler
s元组构建我的模块
,而不必重新指定它们的stackDepth
s@Magix-通过使用Event\u Handler
s的可变列表示例改进答案。是的,模板类型推断有效。模板数字推断也一样。这(几乎)是个奇迹。我仍然有一些错误需要修复,但阻塞问题似乎消失了。我非常感谢你!实际上我不想把它作为一个纯模板参数,而是作为构造函数中的一个实例。这个技巧是否可行?我一直在摆弄它,但没有成功(见问题编辑)@Magix-不完全确定是否理解,但…答案有所改进。
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...>>
{
// ...
};
#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;
}
#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>{});
}