mercredi 6 juillet 2016

Variadic members in non-template class

I'm trying to write a class Invocation which has a templated constructor:

template<typename F>
class Invocation {
public:
    template<typename... Args>
    Invocation(F&& f, Args&&... args)
    { /* store f and args somewhere for later use */ }

    ...
};

Normally I would parameterized the Invocation class itself with both F and Args..., but in this case I need a uniform type for a given F, so I'm trying to find a way to store args... of any types inside a Invocation<F>, and to incur as little performance hit as possible. (This might not be the best design, but it can be an interesting exercise.)

One thought is to use virtual functions:

template<typename F>
class ArgsBase {
public:
    // discard return value
    virtual void invoke(F&& f) = 0;
};

template<typename F, typename... Ts>
class Args : public ArgsBase<F> {
public:
    Args(Ts&&... args) : args_(std::forward<Args>(args)...) {}

    void invoke(F&& f) override
    {
        /* somehow call f with args_ (something like std::apply) */
        ...
    }

private:
    std::tuple<Ts&&...> args_;
};

And then in the Invocation<F> class, we can for example have an std::unique_ptr<ArgsBase<F>> member, which points to an Args<F, Ts...> object constructed in the Invocation<F> ctor. And we can call its invoke virtual method when needed.

This is just one random idea I came up with. Is there any other way to achieve this? Ideally without the overhead of virtual functions or anything like that?

Aucun commentaire:

Enregistrer un commentaire