Bia*_*sta 2 c++ templates template-meta-programming variadic-templates c++11
假设我在编译时要执行一些操作:
enum class Action {A, B};
Run Code Online (Sandbox Code Playgroud)
现在我编写一个模板可变参数函数,它按顺序执行一个可能的动作组合:
template <Action a>
void applyAction();
template <typename = void>
void applyActions() {}
template <Action a, Action... as>
void applyActions() {
applyAction<a>();
applyActions<as...>();
}
Run Code Online (Sandbox Code Playgroud)
这段代码很好.确实:
void foo() {
applyActions<Action::A, Action::B>();
}
Run Code Online (Sandbox Code Playgroud)
正确生成:
call void applyAction<(Action)0>()
call void applyAction<(Action)1>()
Run Code Online (Sandbox Code Playgroud)
为了实现扩展包终止,我不得不声明虚函数:
template <typename = void> void applyActions() {}
Run Code Online (Sandbox Code Playgroud)
这对我来说非常"难看",因为它提供了调用泛型类型的可能性.
在C++ 11中,有没有办法声明一个接受空参数包的可变参数函数?
当然,它的声明不必带来所需函数的模糊性:
template <Action a, Action... as>
void applyActions();
Run Code Online (Sandbox Code Playgroud)
就像是:
template <Action.. = {}>
void applyActions() {}
Run Code Online (Sandbox Code Playgroud)
这是一个不可编译的例子,因为调用含糊不清.但它给出了我想要实现的目标.
另一种构造它的方法,以便您可以删除"丑陋"的默认值,如下所示,它也会删除递归,并且可以使用空操作参数包,
#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;
}
Run Code Online (Sandbox Code Playgroud)
正如HolyBlackCat所指出的,在c ++ 17中你可以使用折叠表达式,
template <Action... as>
void applyActions() {
(applyAction<as>(), ...);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
221 次 |
| 最近记录: |