I’ve been trying to do this with “native” c++ only, but it doesn’t seem possible, because you have to define the exact class of the member-function in advance. I just want to store a simple function pointer as a variable inside a struct, to be called later as a kind of event. I don’t need bound parameters or any fancy functionality that bloats my structs to 10 times their necessary size… There are so many different “DECLARE_…” macros for delegates, dynamic delegates, multicast delegates, dynamic multicast delegates, events… Or should I rather use something from std::function?? I really just need the pointer to the function (not even the object instance). I would simply store it as a void*, if the compiler would let me cast accordingly…
I’d suggest to use an Interface in that case, as it gives you at least some type safety while still allowing you to use a regular typed C++ function pointer to a member function (although, to be honest, I consider that part of the C++ syntax horrible…).
However, if you’d prefer to use type erasure and want to use UE4 types (what I’d recommend, as those interact properly with UE4’s memory management), I’d suggest a regular DECLARE_DELEGATE_whatever
, as those are probably the most simple type unreal offers for that purpose. I’d bind the function using the AddUObject(object, function)
syntax, as this will keep a weak pointer to the object on which the function should be called, and will not call the function if the object has been destroyed.
And just to give you a short reminder:
DECLARE_DELEGATE_*
: A C++ only delegate, to which only one function can be bound at a time
DECLARE_MULTICAST_DELEGATE_*
: A list of delegates for C++ only. Meaning an arbitrary number of functions can be bound.
DECLARE_DYNAMIC_*
: A string based delegate, meant to be used with Blueprint
*_Retval*
: A delegate with return value (of course only makes sense for non-multicast delegates).
DECLARE_EVENT_*
: Just like a delegate, but can only be broadcast by the owning class.
Thanks for the info. It does clear things up.
I am currently trying to use std::function in order to support member function pointers to not-pre-defined classes, but no matter what I do, I come to a point where the compiler comes up with some error, politely indicating that pointers to member-functions must always be typed at compile-time in C++, which sucks hard, if it’s true… Using common base-types is not helping at all.
Interfaces are a bit too static. I need all this for a kind of “managed references/pointers” system, where basically every reference works both ways and objects are automatically informed about destruction and other things. So, depending on what types of objects a given object references and what for, I need a flexible number of callback-functions for each. And since these reference structs only make sense when using them as template, I can’t fully expose them to the engine anyway. Otherwise half my code would be casts…
Naturally, I try to keep these structs as small as humanly possible. The referenced objects are, of course, the most important part, and I don’t necesarily want another redundant pointer inside a delegate, which probably has a lot of other “comfy” feature related data as well.
But I guess, I may not have another choice…