0

I have a problem which I can't get my head wrapped around. I have two type definitions for callbacks (used by lambdas later on):

typedef std::function<void(Payload1 Payload)> Callback1;
typedef std::function<void(Payload2 Payload)> Callback2;

Where as Payload1 and Payload2 are different structs containing event payload data. Then I got two arrays (as I am using, those are TArrays, but that doesn't matter), which contain the callbacks:

TArray<Callback1> Callback1Array;
TArray<Callback2> Callback2Array;

And a templated function which should add the callback into the array where it fits in:

template<typename CallbackType>
void SubscribeToEvent(CallbackType Callback)
{
    // If CallbackType is Callback1
    Callback1Array.Add(Callback);

    // Else If CallbackType is Callback2
    Callback2Array.Add(Callback);
}

I am not sure how I can express the statements I wrote in the comments. It will obviously fail if it tries to add a Callback2 type into the Callback1 array, so I somehow need to check the type, and only add it into the right array, and don't even try to add it in the others. Is this possible?

Thank you :)

Johnny Verbeek
  • 143
  • 1
  • 11

2 Answers2

1

With std::tuple you may do something like:

template <typename ... Ts>
class Foo
{
public:
    template <typename T>
    using Callback = std::function<void(T)>;

    template <typename T>
    using EventArray = TArray<Callback<T>>;


    template <typename T>
    void SubscribeEvent(Callback<T> callback)
    {
        GetCallbackArray<T>().Add(callback);
    }

private:
    template <typename T>
    EventArray<T>& GetCallbackArray() { return std::get<EventArray<T>>(eventCallbacks); }

private:
    std::tuple<EventArray<Ts>...> eventCallbacks;
};

using MyClass = Foo<FRpcEventPayload_Ready /*, ...*/>;
Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

To answer the question directly, you could write what you commented

template<typename CallbackType>
void SubscribeToEvent(CallbackType Callback)
{
    if constexpr(std::is_same_v<CallbackType, Callback1>)
        Callback1Array.Add(Callback);

    if constexpr(std::is_same_v<CallbackType, Callback2>)
        Callback2Array.Add(Callback);
}

But that looks like gross misuse of if constexpr

This is typically where you overload your SubscribeToEvent instead of using templates.

void SubscribeToEvent(Callback1 Callback)
{
    Callback1Array.Add(Callback);
}

void SubscribeToEvent(Callback2 Callback)
{
    Callback2Array.Add(Callback);
}
Passer By
  • 19,325
  • 6
  • 49
  • 96