c++ - 将 std::function 绑定(bind)到不同对象实例的相同函数

标签 c++ c++11 std-function

是否可以重新绑定(bind) std::function 以指向相同的函数但具有不同的对象实例?

如果我有一个对象,它有一个绑定(bind)到另一个函数的 std::function,但是如果那个对象被复制到另一个实例,我想将 std::function 重新绑定(bind)到那个新实例而不是旧实例。

#include "stdafx.h"
#include <iostream>
#include <functional>

class EventHandler
{
public:
    int Num;
    std::function<int()> OnEvent;

    EventHandler (int inNum)
    {
        Num = inNum;
    }

    EventHandler (const EventHandler& other)
    {
        Num = other.Num;
        OnEvent = other.OnEvent; //TODO:  Need some way to redirect the std::function to the new instance rather than having the delegate point to the original object's handler.
    }

    int HandleEvent ()
    {
        return Num;
    }
};

int main()
{
    EventHandler a(4);
    a.OnEvent = std::bind(&EventHandler::HandleEvent, a);
    EventHandler b(a);
    b.Num = 5;
    //Uncommenting the line below is a manual way of redirecting event handler to the new instance.
    //b.OnEvent = std::bind(&EventHandler::HandleEvent, b);

    int aResult = a.OnEvent();
    int bResult = b.OnEvent();

    //This will print out 4 and 4 instead of 4 and 5 since b is still bound to a's event handler.
    std::cout << "aResult=" << aResult << "  bResult=" << bResult << '\n';

    return 0;
}

我愿意使用 std::function 的包装器来存储附加信息。

最佳答案

下面的代码引入了一个binding_function<R(Args...)> ,它被称为 function<R()> , 并且参数可以在构造后随时重新绑定(bind)(假设它不是 nullptr )。

#include <functional>
#include <tuple>
#include <utility>
#include <memory>
#include <iostream>

template <typename T>
class binding_function;

template <typename R, typename... Args>
class binding_function<R(Args...)> : std::function<R()>
{
  using base_function = std::function<R(Args...)>;
  using binded_function = std::function<R()>;
  base_function base;

public:
  binding_function() = default;

  template <typename BaseF, typename... TArgs>
  binding_function(BaseF&& f, TArgs&&... args)
    : base(std::forward<BaseF>(f)) {
    rebind(std::forward<TArgs>(args)...);
  }

  template <typename... TArgs>
  void rebind(TArgs&&... args)
  {
    static_cast<binded_function&>(*this) = 
      std::bind(base, std::forward<TArgs>(args)...);
  }

  using binded_function::operator();
};

class EventHandler
{
public:
    // change type of OnEvent to binding_function
    binding_function<int(EventHandler)> OnEvent;

    // others remain the same
};

int main()
{
    EventHandler a(4);

                // first binding
    a.OnEvent = {&EventHandler::HandleEvent, a};
    EventHandler b(a);
    b.Num = 5;
    b.OnEvent.rebind(b);  // rebinding

    int aResult = a.OnEvent();
    int bResult = b.OnEvent();

    //This will print out 4 and 4 instead of 4 and 5 since b is still bound to a's event handler.
    std::cout << "aResult=" << aResult << "  bResult=" << bResult << '\n';

    return 0;
}

关于c++ - 将 std::function 绑定(bind)到不同对象实例的相同函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37693605/

相关文章:

c++ - 使用 OpenCV 的 C++ 图像的 SNR

c++ - 如何在 C++ 中打印希腊字母 delta

c++ - 使用派生类中的成员在父类中初始化 std::function

C++ 函数式 : bind classes method through pointer

c++ - 从 std::function 调用签名中推导出模板参数

c++ - 通过构造函数自定义排序映射

c++ - Sizeof() 的 VBA 等价物?

c++ - 类链中的转换

c++ - 如何将大量选项组织到一个变量中,然后调用该变量

c++11 使用 chrono 作为语法糖