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