/cpp-delegates

Approximation of C# Delegates, Funcs and Actions on C++

Primary LanguageC++

CppDelegates

Approximation of C# Delegates, Funcs and Actions on C++

How to use it

Even though the three different classes (Delegate, Func and Action) store functions to use them in the future, they serve different purposes. Let's explain them one by one.

Action

His purpose is to store functions whose return type is always void with 0 parameters.

void foo() { std::cout << "Something funny"; }

Action action;
action += foo;

The operator += adds the functions to later be called using the Invoke method.

action.Invoke();
// Prints: Something funny

All of the three classes support function removal by using '-='

action -= foo;
action.Invoke();

// Prints: Nothing.

Func

His purpose is to store functions whose return type is always void with 0 or more parameters.

void print(int x, char a) { std::cout << x << a; }

Func<int, char> func;
func += print;
func += print;

func.Invoke(5, 'A');
// Prints: 5A5A

Delegate

His purpose is to store functions whose return type could be whatever, with 0 or more parameters.

Delegate<int()> delegate;

delegate += []() { return 1; };
delegate += []() { return 2; };
delegate += []() { return 3; };

A nice feature of the Delegate is that the Invoke method returns a std::vector storing the return values of the functions.

for (const auto &item : delegate.Invoke()) std::cout << item;
// Prints: 123

As with Funcs, you can also pass parameters to the Invoke method.

int square(int x) { return x * x; }

Delegate<int(int)> delegate;
delegate += square;

std::cout << delegate.Invoke(2)[0];
// Prints: 4

Frequent questions

Can I add member functions?

Yes! Perhaps is not in the most beautiful way, but still does the trick. You just need to use lambdas like this.

Object obj;
action += [&]() { obj.something(); } // You can even instantiate the object inside the lambda.

How do I pass parameters to the functions?

Again lambdas. Don't ask me, they do anything. You could use std::bind but clang-tidy advices against it.

action += []() { print(5, 'A'); };
action += []() { print(6, 'B'); };

action.Invoke();
// Prints: 5A6B

Something else you didn't mention?

Thanks for asking. The operator += is overloaded to accept a vector.

delegate += { foo, bar };

At difference of C#, delegates can be copied by value.

Delegate<int> delegate(copyMePls); // This is possible.

You can also reset or clear the delegate with delegate.Clear()