Passing reference to function via TFunction fails on UFUNCTIONs

I am attempting to make a little bit easier system for calling a cosmetic change on multicast, by networking. For that I am attempting to use a little lambda like so, and having a function ref as an argument:

void RunMulticast(TFunction<void()> Callback);

UFUNCTION(Server, Reliable)
void Server_RunMulticast(TFunction<void()> Callback);

UFUNCTION(NetMulticast, Reliable)
void Multicast_RunMulticast(TFunction<void()> Callback);

and in .cpp:

void AGamePlayerCharacter::RunMulticast(TFunction<void()> Callback)
{
    if (IsLocallyControlled())
    {
       Callback();
    }
    
    Server_RunMulticast(Callback);
}

void AGamePlayerCharacter::Server_RunMulticast_Implementation(TFunction<void()> Callback)
{
    Multicast_RunMulticast(Callback);
}

void AGamePlayerCharacter::Multicast_RunMulticast_Implementation(TFunction<void()> Callback)
{
    if (!IsLocallyControlled())
    {
       Callback();
    }
}

Calling the function:

RunMulticast([this]
{
    ...
});

However, no matter what I do the compiler says:
Unable to find 'class', 'delegate', 'enum', or 'struct' with name 'TFunction'
In the header declarations for the two networking UFUNCTIONs.

Upon looking online a little, this appears to mean that TFunction is not supported in UFUNCTIONs. If I try the basic C++ std::function<void()> I sadly get the same error…
If there are any alternatives to pass a function ref, that would be very appreciated!

TFunction isn’t supported by the reflection system, and it can’t be serialized, but anything put in an RPC must be serializable. I think your only option here would be to use a delegate:

DECLARE_DYNAMIC_DELEGATE(FCallback);

void RunMulticast(FCallback Callback);

UFUNCTION(Server, Reliable)
void Server_RunMulticast(FCallback Callback);

UFUNCTION(NetMulticast, Reliable)
void Multicast_RunMulticast(FCallback Callback);

Note that this means any functions you pass will themselves need to be declared a UFUNCTION() (which means, sadly, you cannot use a lambda – there’s no way around this), and you’d pass them like so (pretty syre this works; I usually use BindDynamic instead though):

RunMulticast(FCallback::CreateDynamic(this, &AGamePlayerCharacter::MyFunction);

And execute them like this:

void AGamePlayerCharacter::RunMulticast(TFunction<void()> Callback)
{
    if (IsLocallyControlled())
    {
       Callback.ExecuteIfSafe(); // Might be ExecuteIfBound, I can't quite remember
    }
    
    Server_RunMulticast(Callback);
}

If you’d like my opinion though, unless you have tons and tons of these or need it to be extensible (ie, accepting callbacks that you don’t even know exist), I think it would make more sense to just make each one a separate multicast, rather than passing a callback through the multicast.

Yeah, that was what I decided to do, in fact by implementation eventually made it so I only needed one of these functions! If I do need something very extendable in the future, however, I will probably use delegates