我正在尝试用C ++编写一个非常小的状态机。我希望状态是机器类的方法,并且每个状态在运行时都应该返回要移动的新状态。当然,我正在使用一些typedef来帮忙。
template <typename C, typename E>
using State = State<C, E> (C::*)(Stream<E>&);
状态应该是成员函数(在类C
中),它接受流对象并产生新状态。我收到以下错误。
fsm.hpp:8:15: error: ‘State’ does not name a type
using State = State<C, E> (C::*)(Stream<E>&);
显然,State
尚未在声明State
的行上声明。据我所知,没有办法“转发声明”一个typedef,那么声明这个类型名称的恰当方法是什么?
答案 0 :(得分:2)
我不确定我是否可以解释为什么你尝试过的东西没有工作 - 我不知道是否允许using
声明是自我指涉的,也许他们不是。
但是,当然,在类模板中,当前正在定义的类的名称被注入到类范围中,因此您可以这样做。
在这个版本中,我创建了一个类型,它是一个成员函数指针的瘦包装器。我相信优化器应该基本上消除它这个包装器,但是它可以通过利用注入的类名来实现你想要的。
这在gcc 5.2.0中编译并运行
template <typename T>
struct Stream {};
template <typename C, typename E>
class State {
typedef State (C::*func_t)(Stream<E>&);
func_t f_;
public:
State(func_t _f) : f_(_f) {}
State operator()(C & c, Stream<E> & s) const {
return (c.*f_)(s);
}
};
struct Foo {
State<Foo, int> state_one(Stream<int> &) { return &Foo::state_two; }
State<Foo, int> state_two(Stream<int> &) { return &Foo::state_one; }
};
int main() {
Foo f;
Stream<int> s;
f.state_one(s);
}