Using std::apply with variadic packs

  • A+
Category:Languages

I am trying to create a generic class that takes a pack of types, stores them in a tuple, and can apply a function over them.

What I tried so far is the following:

#include <tuple> struct Base{     virtual void base_function() = 0; };  template<typename ...T> struct A : public Base{     std::tuple<T...> as;     A(T... pack):as(pack...){};     void base_function(){         std::apply([](auto t){t.base_function();}, as);     } };  struct B : public Base{     void base_function(){}; };   struct C : public Base{     void base_function(){}; };  struct D : A<B, C>{     D():A(B(),C()){}; }; 

I expected apply to be called on base_function from class B and C when calling base_function on D. But the compiler generates the following error:

error: no matching function for call to
'__invoke(A<T>::base_function() [with T = {B, C}]::<lambda(auto:1)>, std::__tuple_element_t<0, std::tuple<B, C> >&, std::__tuple_element_t<1, std::tuple<B, C> >&)'

 


First parameter of std::apply should be a functor with same arity that number of elements of the tuple, so variadic in your case:

template <typename ...Ts> struct A : public Base{     std::tuple<Ts...> as;     A(Ts... pack) : as(pack...){}      void base_function(){         std::apply([](auto&... ts){(ts.base_function(), ...);}, as);     } }; 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: