如何简化调用语法以接受泛型方法指针的函数C ++ 14

时间:2017-09-12 03:50:07

标签: c++

我正在为Actor系统设计一个消息队列,其中消息队列包含std :: function对象。将消息添加到队列的客户端代码具有复杂的语法,我想简化。一些示例代码:

class Actor
{
    std::deque<std::function<void()>> fMessageQueue;

    template <class F, class ... Args>
    void AddMessage(F &&fn, Args && ... args)
    {
        fMessageQueue.push_back(std::bind(std::forward<F>(fn), std::forward<Args>(args)...));
    }
}

class MyActor : public Actor
{
    void Behaviour1(float arg) {/*do something*/}
}

要使用上述课程,我可以这样做:

int main(int argc, const char **argv)
{
    MyActor a;
    a.AddMessage(&MyActor::Behaviour1, &a, 1.0f);  // redundant 2nd argument &a, needed by std::bind()
}

理想情况下,我想使用以下代码语法:

int main(int argc, const char **argv)
{
    MyActor a;
    a.AddMessage(&MyActor::Behaviour1, 1.0f);  // notice no 2nd argument &a
}

我希望客户端API不需要第二个实例&#39; a&#39; (用作std :: bind()的第二个参数)。

在搜索网络时,我设法找到了一些接近我想要实现的东西,但是参数语法是相反的:

template <class M> struct Behaviour;
template <class C, class ... Args> struct Behaviour<void(C::*)(Args ...)>
{
    using M = void (C::*)(Args ...);
    template <M mp> static void Call(C *target, Args && ... args)
    {
        target->fMessageQueue.push_back(std::bind(mp, target, args ...));
    }
};
#define MSG(m) Behaviour<decltype(m)>::Call<m>

示例呼叫使用将是:

int main(int argc, char **argv)
{
    MyActor a;
    Actor::MSG(&MyActor::Behaviour1)(&a, 1.0f);
}

这稍微清晰一点,但仍然不太像我理想的调用语法。我也不喜欢宏观味精。最简单的API调用语法是:

a.AddMessage(&MyActor::Behaviour1, 1.0f);

有谁知道如何简化调用语法,以便客户端不必指定参数#2?

0 个答案:

没有答案