我正在尝试创建有限状态机层次结构类型结构。我想做的是检查当前状态是否不返回,然后检查是否所有下一个状态都存在。一旦其中之一发生故障,它也会返回。
我不确定是否可以使用折叠表达式或可变参数包扩展来完成它,但是我一直在错误地发现参数包没有被扩展。我不确定是否可以这样做,或者是否需要辅助功能或其他机制。
这是我的方法:
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
}
};
答案 0 :(得分:1)
要使用fold-expression,您需要可以折叠的东西。您需要为参数包中的每个元素提供一些表达式。您需要的表达式很复杂:调用bool board::tryActivateCell(const int x, const int y, const int playerValue) {
// Maybe do a check to avoid an overflow if x or y is equal or greater than boardSize
const int& boardValue = board[y][x];
if (boardValue != 0 && boardValue != playerValue) {
// The other player already activate the cell
return false;
}
// Activate the cell with the value of the current player
boardValue = playerValue;
return true;
}
,检查结果等。因此最好将其放在lambda中:
std::find
如果找到所有状态,则 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
。