mardi 13 avril 2021

C++: use void as template argument

I have this minimal class to represent an event which client can subscribe to.
The event can have an data type associated to it, so when it is triggered by a publisher, an argument of that type would be passed to the client's callback:

template<typename Arg, typename Callback = function<void(const Arg&)>>
class Event
{
public:
    Event(Callback c) : mCallback(c){}
    
    void Trigger(const Arg& arg) {
        mCallback(arg);
    }

private:
    Callback mCallback;
};

Now I can create an Event<int> or any other concrete type, but it is really important to me to also allow "empty" event, which has no data associated with it: Event<void>

But sadly that doesn't work:

static void FooVoid() {
    cout << "Look ma, no args!" << endl;
}

static void FooInt(int a) {
    cout << "int arg " << a << endl;
}

int main()
{
    /* Compiles */
    Event<int> eInt(&FooInt);
    eInt.Trigger(42);

    /* Does not compile :(
    Event<void> eVoid(&FooVoid);
    eVoid.Trigger();
    */
    return 0;
}

Is there any way to achieve this desired API? How?

(P.S the solution should work on C++11)

Aucun commentaire:

Enregistrer un commentaire