【问题标题】:Fold Expressions, parameter pack expansion, recursion in class member function折叠表达式、参数包扩展、类成员函数中的递归
【发布时间】:2019-12-25 06:32:57
【问题描述】:

我正在尝试创建有限状态机层次结构类型结构。我要做的是检查当前状态是否存在,如果它不返回,然后检查是否所有下一个状态都存在。一旦其中一个失败,它也会返回。

我不确定是否可以使用折叠表达式或可变参数包扩展来完成,但我一直收到参数包未扩展的错误。我不确定我是否可以这样做,或者我是否需要一个辅助函数或其他一些机制。

这是我的方法:

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
    }
};

【问题讨论】:

  • 请减少问题陈述。很多代码和描述与实际问题无关。
  • @Barry 这有帮助吗?
  • 好多了,谢谢。

标签: c++ recursion c++17 variadic fold-expression


【解决方案1】:

要使用折叠表达式,您需要一些可以折叠的东西。您需要为参数包中的每个元素设置一些表达式。您需要的表达式很复杂:调用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

【讨论】:

  • 我得马上去看看!
  • 好的,我在这方面取得了一些进展,但现在我得到了 C2678:编译器错误 - no operator found which takes a left-hand operand of type 'State&lt;2&gt;' (or there is no acceptable conversion)...
  • 我不得不采用您的方法并在我的State 课程中做类似的事情,现在它就像一个魅力。然而;为了让我的FSM 类使用我的State 类,我必须在我的State 类中定义一个operator==()。您的反馈非常有用,有助于解决我的几个问题。你也给了我实现一套新工具的能力!我现在知道如何在 lambda 上使用 fold expressions 来进行 parameter pack 扩展!
猜你喜欢
  • 1970-01-01
  • 2020-11-29
  • 1970-01-01
  • 2021-10-31
  • 1970-01-01
  • 2012-09-12
  • 2018-08-04
  • 2013-08-04
  • 1970-01-01
相关资源
最近更新 更多