mercredi 5 avril 2017

Is there a type-erased function wrapper in the Standard Library that matches std::thread's constructor semantics?

I need to create a non-template class¹ that needs to hold a callable and its arguments, in order to invoke them at a later point.

Since this class is modelling an async execution, I'd like to give it API and semantics matching the ones of std::thread / std::async:

class Async {
public:
    template <typename Function, typename... Args >
    explicit Async(Function&& f, Args &&... args)
    {
         // perform a (decay) copy of the args,
         // store f and the copy somewhere
    }

    void call() 
    {
        // to be possibly called in a different thread;
        // call the function stored. no need to return the results
    }

private:
    // which data members?
};

The first thing that came into my mind is use a std::function<void()> as the only data member, and initialize it from a std::bind over the arguments.

However, this doesn't work: std::function and std::bind don't support move-only types, and std::bind simply does not work in terms of std::invoke (and it does a lot of extra magic, like recursively resolve bindings).

Am I missing some easy-to-reach solution available in the Standard Library to implement this, or should I deploy my own binder and type-erased function wrapper classes?


¹ Long story short: this class needs to inherit from a base class with virtual methods, so making this class a template class would cause the usual code bloat and clashes due to the duplication of virtual tables and virtual methods appearing everywhere.

Aucun commentaire:

Enregistrer un commentaire