折叠表达式、参数包扩展、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.