C ++变量参数

use*_*664 3 c++ templates function variadic

我有一个带有状态机的类,并且希望有一个入口点将事件传递给状态机。该事件伴随有事件特定的数据,然后我希望将其分发给处理程序。所以看起来像这样...

class X
{
  public:
    ...
    template<typename... A> void fsm(eEvent eventId, const A&... eventData);

  private:
    ...
    void eventA(int a, double b);
    void eventB(std::string a);
    void eventC(unsigned long a);
Run Code Online (Sandbox Code Playgroud)

};

...看起来像这样的调用...

X x;

x.fsm(eEventA, -1, 2.0);
x.fsm(eEventB, "xyz");
x.fsm(eEventC, 42);
Run Code Online (Sandbox Code Playgroud)

我在弄清楚如何获取模板函数来调用正确的处理程序时遇到了麻烦。如果我只是打开eventId并通过变量参数,它将不会编译,因为对于所有参数组合都不存在处理程序(例如,没有eventA()处理程序接受eventB()参数,我不会仍然要)。

我的猜测是有一些优雅的方法可以做到这一点,但这让我难以理解。

Pot*_*ter 5

选项1.沟渠杂色

如果没有C ++ 11模板参数包,自然的选择是为每个事件声明一个类型,并从基本事件类型继承,然后将其打包eventData。那就是我的建议。您可以使用动态类型来验证是否已分派正确的事物,如果这会使事物变慢,请在生产模式下禁用检查。

选项2. PTMF

使用指向成员函数的指针向调度程序标识事件。这消除了枚举的需要,并直接将分发的类型编码到模板化的分发器中。

但是,这确实要求分派的函数为public

template<typename... P, typename... A> void fsm(void (X::*event)( P ... ),
    const A&... eventData) {
    this->*event( eventData ... );
}

x.fsm( &X::eventB, 5, 1.3 );
Run Code Online (Sandbox Code Playgroud)