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
Comprehensive course covering advanced concepts, and how to use them on large-scale projects.
View Course