Skip to content

Instantly share code, notes, and snippets.

@ananace
Created April 26, 2016 23:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ananace/975f379186c4fad3a11ef3f2e2d9b487 to your computer and use it in GitHub Desktop.
Save ananace/975f379186c4fad3a11ef3f2e2d9b487 to your computer and use it in GitHub Desktop.
Simple C#-like event handling in C++11
#pragma once
#include <functional>
#include <vector>
template<typename... Args>
class Event
{
public:
typedef std::function<void(Args...)> EventHook;
Event() = default;
Event(const Event&) = default;
~Event() = default;
Event& operator=(const Event&) = default;
Event& operator+=(const EventHook& hook)
{
mHooks.push_back(hook);
return *this;
}
template<typename Class>
Event& addMember(void(Class::*funcPtr)(Args...), Class* classPtr)
{
mHooks.push_back([funcPtr, classPtr](Args... args) {
std::invoke(std::mem_fn(funcPtr), classPtr, std::forward<Args>(args)...);
});
return *this;
}
void operator()(Args... args) const
{
for (auto& hook : mHooks)
hook(std::forward<Args>(args)...);
}
private:
std::vector<EventHook> mHooks;
};
#include "Event.hpp"
#include <cassert>
void sum(int a, int& out)
{
out += a;
}
class Averager
{
public:
Averager(int value)
: mValue(value)
{
}
void average(int a, int& test)
{
test = (a + mValue) / 2;
}
private:
int mValue;
};
int main(int argc, char** argv)
{
Event<int, int&> testEvent;
testEvent += sum;
int result = 4;
testEvent(2, result);
assert(result == 2 + 4);
// TODO: Event.clear(), event -=, etc.
// Exercise for the reader.
testEvent = Event<int, int&>();
Averager avg(8);
testEvent.addMember(&Averager::average, &avg);
testEvent(4, result);
assert(result == (4 + 8) / 2);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment