C++11多播委托实现

C++11 multicast delegate implementation

本文关键字:实现 多播 C++11      更新时间:2023-10-16

我想将代理添加到我的游戏引擎中。我已经习惯了c#中的它们,现在我离不开它们。

我在这里和外部源上看到了一些实现,但它们不是多播的。委托一次只允许存储一个侦听器。有人知道在内存/性能方面有什么好的支持+=和-=的实现吗?我试过用可变模板写我的文章,但我还没有做到。

编辑:这就是我到现在为止所做的:

template<typename ... Args>
class Delegate
{
public:
   Delegate() =default;
   ~Delegate() = default;
   template<typename U>
   Delegate& operator += (const U &func)
   {
        _listeners.push_back(std::function<void(Args...)>(func));
        return *this;
   }
   template<typename Class, typename Method>
   Delegate& operator += (const std::function<void(Args...)> func)
   {
        _listeners.push_back(func);
        return *this;
   }
   void operator() (Args... params)
   {
        for (auto listener : _listeners)
        {
            listener(params...);
        }
   }
   private:
       std::list<std::function<void(Args...)>> _listeners;
};

它运行得非常好。在这里你可以看到如何使用它:

Delegate<std::string> del;
del += std::bind(&GameScene::print, this, std::placeholders::_1);
del += [](const std::string& str) { log(str.c_str()); };
del("text");

我知道我几乎一直都会使用std::bind版本,因为这是在事件消息系统中使用的,实例将使用类方法订阅委托(通过类方法,我指的不是静态方法,而是类的方法)。是否有任何改进std::bind部分的方法?我认为当你必须添加一些带有占位符的函数等时,这有点丑陋和烦人…

干杯。

基本上,一个简单的C++11实现可能看起来像:

#include <vector>
#include <functional>
class Foo
{
    public:
        std::vector< std::function< void() > > onSomething;
};
int main( void )
{
    Foo f;
    f.onSomething.push_back( [&] { /* Do something... */ } );
    f.onSomething.push_back( [&] { /* Do something else... */ } );
    return 0;
}

注意std::function的使用,它允许在vector中存储lambda
然后,您将能够遍历向量,并执行每个lambda。

然后,当然,操作员过载和线程安全(如果需要的话)。。。但这应该是微不足道的。