C++ Delegate to member function using std::function and std::bind not calling function

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • C++ Delegate to member function using std::function and std::bind not calling function

      This is baffling me. Below we have three classes, the Paddle class and two wrapper classes that call members of the Paddle object.

      The Paddle object isn't working with the delegates, but works when invoked from wrapper classes. All functions have the same signatures and overloads.

      The compiler throws no errors, and the code runs fine but has the above unexpected behavior.

      Why is this happening?

      Source Code

      1. // sf::Transformable has 2 overloaded member functions:
      2. // void setPosition(float x, float y);
      3. // void setPosition(const Vector2f& position);
      4. class Paddle : public sf::Drawable, public sf::Transformable {}
      5. Paddle paddle{};
      6. // wrap the calls in another class with the same overload signatures as paddle
      7. // used to show delegate working with overloads
      8. class A
      9. {
      10. public:
      11. void setPosition(sf::Vector2f& v) {
      12. paddle.setPosition(v);
      13. }
      14. void setPosition(float x, float y) {
      15. paddle.setPosition(x, y);
      16. }
      17. };
      18. // inherit members from A
      19. // used to show delegate working with inherited overloads
      20. class B : public A {};
      21. // delegate typedef
      22. typedef std::function<void(float,float)> TranslateDelegate;
      23. // create wrapper classes
      24. A a{};
      25. B b{};
      26. // create 3 delegates
      27. TranslateDelegate pda = std::bind(static_cast<void(A::*)(float, float)>(&A::setPosition), a, std::placeholders::_1, std::placeholders::_2);
      28. TranslateDelegate pdb = std::bind(static_cast<void(B::*)(float, float)>(&B::setPosition), b, std::placeholders::_1, std::placeholders::_2);
      29. TranslateDelegate pdp = std::bind(static_cast<void(Paddle::*)(float, float)>(&Paddle::setPosition), paddle, std::placeholders::_1, std::placeholders::_2);
      30. pda(300.f, 900.f); // sets paddle position correctly
      31. pdb(300.f, 900.f); // sets paddle position correctly
      32. pdp(300.f, 900.f); // DOES NOTHING!!
      Display All
    • Figured it out. It seems for paddle, I needed to pass the address to std::bind, unlike a and b:

      Source Code

      1. TranslateDelegate pdp = std::bind(static_cast<void(Paddle::*)(float, float)>(&Paddle::setPosition), &paddle, std::placeholders::_1, std::placeholders::_2);


      I'm assuming this is due to the fact that the function in A and B would work either in context or being called as static class functions.
    • I am wondering if this is because Paddle's functions are located in the V-table, where it seems as though A & B's are not, I could be wrong, but hey give it a try (changing paddle to not inherit from the base classes and get rid of the virtual function calls), it is worth learning if that was the cause.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • I also agree that they don't look necessary however It doesn't seem like that would cause any issue in this case.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz