折叠表达式、参数包扩展、class 成员函数中的递归
Fold Expressions, parameter pack expansion, recursion in class member function
我正在尝试创建有限状态机层次结构。我想要做的是检查当前状态是否存在,如果不存在 return,然后检查是否所有下一个状态都存在。一旦其中之一失败,它也会 return 。
我不确定是否可以使用折叠表达式或可变参数包扩展来完成,但我一直收到参数包未扩展的错误。我不确定我是否可以这样做,或者我是否需要辅助函数或其他机制。
这是我的方法:
template<unsigned N>
class FSM {
public:
std::vector<State<N>> states;
// ... other parts of class
template<typename Current, typename... NextStates>
void addStateTransition(Current* currentState, NextStates*... nextStates) {
// look to see if the current state is a state in our container.
auto current = std::find(states.begin(), states.end(), currentState);
if (current == states_.end()) {
std::cout << "Could not find " << currentState->id_ << " in this State Machine.";
return;
}
// Able to use fold expressions or not to check if all of the next states are in our container?
auto next = std::find(states.begin(), states.end(), nextStates);
// ? I've tried the ellipsis inside, outside and on both sides of the ending parenthesis, and none of them work.
if (next == states.end()) {
std::cout << "Could not find " << nextStates->id_ << " in this State Machine.";
return;
}
// if all of nextStates... are found, do something else here
}
};
要使用折叠表达式,您需要可以折叠的东西。您需要为参数包中的每个元素提供一些表达式。您需要的表达式很复杂:调用 std::find
、检查结果等。所以最好将它放在 lambda 中:
auto lookup = [&](auto nextState) {
// one single find
auto it = std::find(states.begin(), states.end(), nextState);
if (it == states.end()) {
std::cout << "Could not find " << nextState->id_ << " in this State Machine.";
return false;
}
return true;
};
// fold over that
bool const allFound = (lookup(nextStates) && ...);
如果找到所有状态,allFound
将是 true
,如果至少有一个状态丢失,则 false
...在这种情况下,将记录一些内容。这也处理空包......如果 nextStates...
是空的,allFound
是平凡的 true
.
我正在尝试创建有限状态机层次结构。我想要做的是检查当前状态是否存在,如果不存在 return,然后检查是否所有下一个状态都存在。一旦其中之一失败,它也会 return 。
我不确定是否可以使用折叠表达式或可变参数包扩展来完成,但我一直收到参数包未扩展的错误。我不确定我是否可以这样做,或者我是否需要辅助函数或其他机制。
这是我的方法:
template<unsigned N>
class FSM {
public:
std::vector<State<N>> states;
// ... other parts of class
template<typename Current, typename... NextStates>
void addStateTransition(Current* currentState, NextStates*... nextStates) {
// look to see if the current state is a state in our container.
auto current = std::find(states.begin(), states.end(), currentState);
if (current == states_.end()) {
std::cout << "Could not find " << currentState->id_ << " in this State Machine.";
return;
}
// Able to use fold expressions or not to check if all of the next states are in our container?
auto next = std::find(states.begin(), states.end(), nextStates);
// ? I've tried the ellipsis inside, outside and on both sides of the ending parenthesis, and none of them work.
if (next == states.end()) {
std::cout << "Could not find " << nextStates->id_ << " in this State Machine.";
return;
}
// if all of nextStates... are found, do something else here
}
};
要使用折叠表达式,您需要可以折叠的东西。您需要为参数包中的每个元素提供一些表达式。您需要的表达式很复杂:调用 std::find
、检查结果等。所以最好将它放在 lambda 中:
auto lookup = [&](auto nextState) {
// one single find
auto it = std::find(states.begin(), states.end(), nextState);
if (it == states.end()) {
std::cout << "Could not find " << nextState->id_ << " in this State Machine.";
return false;
}
return true;
};
// fold over that
bool const allFound = (lookup(nextStates) && ...);
如果找到所有状态,allFound
将是 true
,如果至少有一个状态丢失,则 false
...在这种情况下,将记录一些内容。这也处理空包......如果 nextStates...
是空的,allFound
是平凡的 true
.