c++ - Variadic members in non-template class -


i'm trying write class invocation has templated constructor:

template<typename f> class invocation { public:     template<typename... args>     invocation(f&& f, args&&... args)     { /* store f , args somewhere later use */ }      ... }; 

normally parameterize invocation class both f , args..., in case need uniform type given f, i'm trying find way store args... of types inside invocation<f>, , incur little performance hit possible. (this might not best design, can interesting exercise.)

one thought 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<ts>(args)...) {}      void invoke(f&& f) override     {         /* somehow call f args_ (something std::apply) */         ...     }  private:     std::tuple<ts&&...> args_; }; 

and in invocation<f> class, can example have std::unique_ptr<argsbase<f>> member, points args<f, ts...> object created in invocation<f> ctor. , can call invoke virtual method when needed.

this 1 random idea came with. there other way achieve this? ideally without overhead of virtual functions or that?

update: comments/answers suggest using std::function or lambdas. should've made clear i'm interested in more general case, i.e., variadic stuff might not arguments callable. can want store in class type not parameterized types of these stuff.

as mentioned in comment, wouldn't worry storing arguments value. compiler's copy-elision can generous.

particularly if offer class r-value invoke:

#include <tuple>  template<typename f> class argsbase { public:     // discard return value     virtual void invoke(f&& f) const & = 0;     virtual void invoke(f&& f) && = 0; };  template<typename f, class... functionargs> class args : public argsbase<f> { public:   template<class...ts>     args(ts&&... args) : args_(std::forward<ts>(args)...) {}      template<std::size_t...is, class tuple>       static void invoke_impl(f& f, std::index_sequence<is...>, tuple&& t)     {       f(std::get<is>(std::forward<tuple>(t))...);     }       void invoke(f&& f) const & override     {       invoke_impl(f,                    std::make_index_sequence<std::tuple_size<tuple_type>::value>(),                    args_);          /* somehow call f args_ (something std::apply) */     }      void invoke(f&& f) && override     {       invoke_impl(f,                    std::make_index_sequence<std::tuple_size<tuple_type>::value>(),                    std::move(args_));          /* somehow call f args_ (something std::apply) */     }  private:   using tuple_type = std::tuple<functionargs...>;     tuple_type args_; };  template<class callable, class...myargs>   auto later(myargs&&...args) {   return args<callable, std::decay_t<myargs>...>(std::forward<myargs>(args)...); }  void foo(const std::string&, std::string) { }  int main() {   auto l = later<decltype(&foo)>(std::string("hello"), std::string("world"));   l.invoke(foo);   std::move(l).invoke(foo); } 

Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -