【问题标题】:Is it possible to change the member function pointer from std::bind to lambda?是否可以将成员函数指针从 std::bind 更改为 lambda?
【发布时间】:2020-03-16 13:37:12
【问题描述】:

我用std::functionstd::bind编写了回调方法。

A 类中的std::function 对象func1 指向函数bFoo(int, int),它是B 类的成员。

我的程序中的回调代码:

// Class A - A.h
class A
{
  public:
    template<class T>
    void setCallback(T *pClass, void(T::*pFunc)(int, int));

  private:
    std::function<void(int, int)> func1;
}

template<class T>
inline void A::setCallback(T *pClass, void(T::*pFunc)(int, int))
{
  func1 = std::bind(pFunc, pClass, std::placeholders::_1, std::placeholders::_2); 
}

// Class A - A.cpp
...
func1(x,y);
...

// Class B - B.h
class B
{
  public:
    void bFoo(int x, int y);

  private:
    A a; // instance of class A
}

// Class B - B.cpp
B::B()
{
  a.setCallback(this, &B::bFoo);
}

效果很好。

不过,听说在 C++ 14 及更高版本中,std::bind 可以完全被 lambda 替代,而 lambda 相对于std::bind 有很多优势。

所以我尝试将绑定更改为 lambda 并查找了许多示例,但就我而言,我还没有找到如何将绑定替换为 lambda。

我想使用 lambda 将另一个类的成员函数分配给 std::function,而不是 std::bind

这可能吗?

【问题讨论】:

  • 应该是[=](int x, int y){(pClass-&gt;*pFunc)(x,y);}
  • @HolyBlackCat 你是对的。感谢帮助!

标签: c++ lambda c++14 std-function stdbind


【解决方案1】:

可以通过使用您当前的代码来做到这一点

func1 = [=](int x, int y){ (pClass->*pFunc)(x,y); };

在我看来,最好在调用站点上写出 lambda。 为此,您需要修改setCallback

class A
{
  public:
    template<class T>
    void setCallback(T callback);

  private:
    std::function<void(int, int)> func1;
}

template<class T>
inline void A::setCallback(T callback)
{
  func1 = callback; 
}

然后我们可以使用 lambda 从 Bs 构造函数中调用。

class B
{
  public:
    void bFoo(int x, int y);

  private:
    A a; // instance of class A
}

// Class B - B.cpp
B::B()
{
  a.setCallback([&](int x, int y){ bFoo(x, y); }); // & will capture this
}

【讨论】:

    【解决方案2】:

    简而言之,

    struct A {
        using Callback = std::function<void(int, int)>;
        void setCallback(Callback cb) { func1 = std::move(cb); }
    };
    B::B() { a.SetCallback([this](int x, int y) { bFoo(x, y); }); }
    

    您应该捕获this 以将方法绑定到对象。

    std::bind 应该没有什么问题,除非你为一家知名公司工作,该公司有自己独特的观念,即拥有自己的独特观念。

    【讨论】:

    • 神秘的水果公司,还是这里没有发明所以我们假装它不存在的公司?
    • 不,不使用异常是因为它们非常危险和不合理,手动错误检查和重新抛出肯定要安全得多。他们甚至创建了自己的语言,其中典型的函数调用看起来像 if _, err := F(); err != nil { — 因为手动执行所有操作并且非常冗长会给您更好的控制感,你知道的。
    • 啊哈,我想我可以在第三次猜测中猜出公司(因为我的前两次猜测是摇摆不定),即使你允许我 1e+100 次猜测。
    猜你喜欢
    • 2022-08-18
    • 2018-08-08
    • 1970-01-01
    • 2013-02-22
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    相关资源
    最近更新 更多