Passing and storing lambda function as callbacks

This is a perfectly valid approach to storing event handlers.

However, I would like to point out some details regarding the signature of your function for adding a callback. You worry about passing it by value vs by reference. In your example, you currently have:

void On(EventType OnEventType,std::function<void()>&& Callback)

This is good, as long as you will only ever bind this to rvalues. However, unless there are particular reasons why you want to disallow it, I would recommend that you always have a method which accepts parameters by value or lvalue reference and add the rvalue reference version as a complement, if deemed necessary.

Not having a method which takes an lvalue reference means your code will currently fail to compile given this:

std::function<void()> func([](){/*something clever*/});
// Do something necessary with func, perhaps logging or debug prints.
Button->On(EventType::Click, func);

For simplicity, whenever you're choosing how to pass a value, you can simply follow these guidelines in general:

  • If you need a copy of or intend to modify the value sent in, without wanting to change the actual object passed: pass by value.
  • If you intend to modify the value sent in, and want these changes to affect the actual object passed: pass by reference.
  • If you do not want to change the object passed, but believe it is beneficial to avoid copying: pass by const reference.
  • If you take parameters by value, reference or const reference, and believe there are valuable optimizations which can be achieved using the knowledge that the input parameter is a temporary: also allow to pass by rvalue reference.

Yes. Functions are either raw function pointers or light weight classes that their copy constructor has no side effect, so their copy must act as original object, so this approach is completely ok. But why you pass object by value and then move it to your original container, you can pass reference and then copy it to your container and have an overloaded function that accept an r-value reference (should not be so important).