jeudi 26 avril 2018

C++ API design: is using void* a bad idea?

I am working on an API that I want as generic as possible on the caller side. Main design idea is to provide a signal/slot sort of implementation that allows the user of the API to subscribe to a given set of events, and attach user-defined callbacks to them.

Public interface looks something like this:
RetCallback subscribe(EventEnum& ev, std::function<void(void*)> fn) const; : note the void(void*) signature here. EventEnum is given in a public header file, as well as types definition.

Inner-works of the API would then notify its subscribed observers of the event through a notify method and provide data to forward to the client :

void dummyHeavyOperation() const {
    std::this_thread::sleep_for(2s);
    std::string data = "I am working very hard";
    notify(EventEnum::FooEvent, &data);
}

Client subscribes and casts data to (documented) type as follows:

auto subscriber = Controller->subscribe(EventEnum::FooEvent, callback);

where

void callback(void* data) {
    auto* myData = (std::string*) data;
    std::cout << "callback() with data=" << *myData << std::endl;

    /// Do things
}

Is this a reasonable design or is this frowned upon? What is your experienced modern C++ developer mind tells you?

Thanks!

Aucun commentaire:

Enregistrer un commentaire