Можно ли изменить указатель на функцию-член с std :: bind на lambda? - PullRequest
0 голосов
/ 16 марта 2020

Я закодировал метод обратного вызова с std::function, std::bind.

std::function объектом func1 в классе A, указывающим на функцию 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 может быть полностью заменен лямбда и лямбда имеет много преимуществ перед std::bind.

Поэтому я попытался изменить привязку к лямбде и просмотрел множество примеров, но в моем случае я не нашел, как заменить привязку к лямбде.

Я хочу назначить функцию-член из другого класса в std::function, используя лямбду, а не std::bind.

возможно ли это?

Ответы [ 2 ]

2 голосов
/ 16 марта 2020

Вкратце,

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 не должно быть ничего плохого, если только вы не работаете на него известная компания, у которой есть свое особенное понятие, у которого есть свои особые понятия.

2 голосов
/ 16 марта 2020

Было бы возможно сделать это с вашим текущим кодом, используя

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

По-моему, лучше вместо этого выписать лямбду на вызывающем сайте. Для этого вам нужно изменить 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; 
}

Затем мы можем вызвать конструктор B с лямбда-выражением.

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...