Member Function Pointers with Templates

Can we use member function pointers with templates to create generic callbacks that work with any class that has a specific method signature?

Yes, we can use member function pointers with templates to create generic callbacks that work with any class having a matching method signature. This is particularly useful for event systems or generic algorithms.

Basic Template Callback

Here's a basic example using a templated callback function:

#include <iostream>

template <typename T>
class Callback {
public:
  using MemberFunc = void (T::*)();

  Callback(T* Instance, MemberFunc Func) :
    Instance{Instance}, Function{Func} {}

  void Execute() { (Instance->*Function)(); }

private:
  T* Instance;
  MemberFunc Function;
};

class Player {
public:
  void Jump() {
    std::cout << "Player jumped!\n";
  }
};

class Enemy {
public:
  void Jump() {
    std::cout << "Enemy jumped!\n";
  }
};

int main() {
  Player player;
  Enemy enemy;

  Callback playerCallback{
    &player, &Player::Jump};
  Callback enemyCallback{&enemy, &Enemy::Jump};

  playerCallback.Execute();
  enemyCallback.Execute();
}
Player jumped!
Enemy jumped!

Generic Event System

Here's a more advanced example with parameter support:

#include <iostream>
#include <vector>
#include <functional>

template <typename ReturnType, typename... Args>
class EventSystem {
public:
  template <typename T>
  using MemberFunc = ReturnType (T::*)(Args...);

  template <typename T>
  void Subscribe(T* Instance,
                 MemberFunc<T> Func) {
    callbacks.push_back(
      [=](Args... args){
        return (Instance->*Func)(args...);
      });
  }

  void Broadcast(Args... args) {
    for (auto& callback : callbacks) {
      callback(args...);
    }
  }

private:
  std::vector<std::function<ReturnType
    (Args...)>> callbacks;
};

class Player {
public:
  void OnDamage(int Amount) {
    std::cout << "Player took " << Amount <<
      " damage\n";
  }
};

class Enemy {
public:
  void OnDamage(int Amount) {
    std::cout << "Enemy took " << Amount <<
      " damage\n";
  }
};

int main() {
  EventSystem<void, int> damageEvent;

  Player player;
  Enemy enemy;

  damageEvent.Subscribe(&player,
                        &Player::OnDamage);
  damageEvent.Subscribe(&enemy,
                        &Enemy::OnDamage);

  damageEvent.Broadcast(50);
}
Player took 50 damage
Enemy took 50 damage

The benefits of this approach include:

  • Type safety through templates
  • Compile-time checking of method signatures
  • Support for any class with matching method signature
  • No need for inheritance or interfaces
  • Flexibility to add or remove callbacks at runtime

This pattern is commonly used in game engines for event systems, input handling, and component-based architectures.

Pointers to Members

Learn how to create pointers to class functions and data members, and how to use them

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Member Function Pointers vs Virtual Functions
Why would we use member function pointers instead of virtual functions when we want to change behavior at runtime?
Member Function Pointer Performance
How do member function pointers impact performance compared to virtual functions or std::function? Are there memory overhead considerations?
Async Member Function Pointers
How can we use member function pointers with asynchronous operations like std::async or thread pools?
Serializing Member Function Pointers
What's the best way to serialize/deserialize member function pointers for saving game state or network communication?
Lambda Member Function Pointers
Is it possible to create a member function pointer to a lambda that's stored as a class member?
Smart Pointers with Member Functions
How can we use member function pointers with smart pointers (shared_ptr, unique_ptr) effectively?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant