[英]Empty Pack Variadic Template
假设我在编译时有一些动作要执行:
enum class Action {A, B};
现在,我编写了一个模板可变参数函数,该函数按顺序执行动作的可能组合:
template <Action a>
void applyAction();
template <typename = void>
void applyActions() {}
template <Action a, Action... as>
void applyActions() {
applyAction<a>();
applyActions<as...>();
}
这段代码很好。 确实:
void foo() {
applyActions<Action::A, Action::B>();
}
正确生成:
call void applyAction<(Action)0>()
call void applyAction<(Action)1>()
为了实现扩展包终止,我必须声明哑元函数:
template <typename = void> void applyActions() {}
这对我来说非常“丑陋”,因为它使调用通用类型成为可能。
在C ++ 11中 ,有没有办法声明一个接受空参数包的可变参数函数?
当然,它的声明不必使所需的功能产生歧义:
template <Action a, Action... as>
void applyActions();
就像是:
template <Action.. = {}>
void applyActions() {}
由于呼叫歧义, 这里是不可编译的示例。 但是它给出了我想要实现的想法。
下面是另一种结构化方式,您可以删除“ ugly”默认值,它也删除了递归,并且可以与空的action参数包一起使用,
#include <iostream>
using namespace std;
enum class Action {A, B};
template <Action a>
void applyAction()
{
std::cout << "Action " << (int)a << std::endl;
}
template <Action... as>
void applyActions() {
using do_= int[];
(void)do_{0, (
applyAction<as>()
,0)...};
}
void foo() {
applyActions<Action::A, Action::B>();
}
void bar() {
applyActions<Action::B, Action::A>();
}
int main() {
foo();
bar();
return 0;
}
正如HolyBlackCat指出的那样,在c ++ 17中,您可以使用fold表达式,
template <Action... as>
void applyActions() {
(applyAction<as>(), ...);
}
在C ++ 11中,有没有办法声明一个接受空参数包的可变参数函数?
是的:存在,而且微不足道
template <Action...>
void applyActions()
问题是,在您的情况下,与一个或多个元素接受的函数冲突
template <Action a, Action... as>
void applyActions()
以及当您调用applyActions<as...>();
带有不为空的as...
包,两个模板都匹配。
使用名称相同但类型不同的模板函数(以及默认值)
template <typename = void>
void applyActions() {}
(IMHO)这是一种非常聪明,便宜且优雅的解决终端问题的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.