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.
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!
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:
This pattern is commonly used in game engines for event systems, input handling, and component-based architectures.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to create pointers to class functions and data members, and how to use them