C++递归函数类型

asy*_*nts 1 c++ recursion

Rob Pike 在 2011 年 (链接) 发表了关于 go 中的词法分析器的演讲,他在那里定义了一个这样的类型:

// stateFn represents the state of the scanner
// as a function that returns the next state.
type stateFn func() stateFn
Run Code Online (Sandbox Code Playgroud)

我想在 C++ 中实现相同的目标,但不知道如何:

// stateFn represents the state of the scanner
// as a function that returns the next state.
type stateFn func() stateFn
Run Code Online (Sandbox Code Playgroud)

注意:这个问题可能有关联(在 Rust 中也是一样)

编辑:

这是我想要实现的目标:

// 01: error C3861: 'statefn_t': identifier not found
typedef std::function<statefn_t()> statefn_t;

// 02: error C2371: 'statefn_t': redefinition; different basic types
typedef std::function<class statefn_t()> statefn_t;

// 03: error C2371: 'statefn_t': redefinition; different basic types
typedef std::function<struct statefn_t()> statefn_t;

// 04: error C2065: 'statefn_t': undeclared identifier
typedef std::function<statefn_t*()> statefn_t;

// 05: error C2371: 'statefn_t': redefinition; different basic types
typedef std::function<class statefn_t*()> statefn_t;

// 06: error C2371: 'statefn_t': redefinition; different basic types
typedef std::function<struct statefn_t*()> statefn_t;
Run Code Online (Sandbox Code Playgroud)

eer*_*ika 5

类型别名不能递归。

要实现像 go 讲座中使用的那样的状态机,您需要定义一个自定义类型:

class state
{
public:
    using fn = std::function<state()>;
    state() {}
    state(fn f) : f(f){}
    operator bool() { return (bool)f; }
    operator fn () { return f; }

private:
    fn f;
};
Run Code Online (Sandbox Code Playgroud)

用法:

state::fn stateEnd()
{
    std::cout << "end\n";
    return {};
}
state::fn stateTransit()
{
    std::cout << "transit\n";
    return stateEnd;
}

state::fn stateStart()
{
    std::cout << "start\n";
    return stateTransit;
}


int main() {
    state::fn s = stateStart;
    while(s = s());
}
Run Code Online (Sandbox Code Playgroud)

替代形式:

class state
{
public:
    state() {}
    template<class T>
    state(T&& t) : f(std::forward<T>(t)){}
    operator bool() { return (bool)f; }
    state operator()() { return f(); }

private:
    std::function<state()> f;
};
Run Code Online (Sandbox Code Playgroud)

用法:

state stateEnd()
{
    std::cout << "end\n";
    return {};
}
state stateTransit()
{
    std::cout << "transit\n";
    return stateEnd;
}

state stateStart()
{
    std::cout << "start\n";
    return stateTransit;
}


int main() {
    state s {stateStart};
    while(s = s());
}
Run Code Online (Sandbox Code Playgroud)