Search code examples
c++variadic-templatesobject-composition

Variadic Template Functor Call


So I've been trying to use variadic templates to compose objects out of more convenient subtypes, but I'm having trouble getting it to do exactly what I want.

template<class ...Functor>
struct SeqMethod:public Functor...{
  template<class F>
  void call(F& a){
    F::operator()();
  }
  template<class F,class ... funcs>
  void call(){
    F::operator()();

    call<funcs...>();
  }
  public:
  void operator()(){
    call<Functor...>();
  }
};

This isn't valid syntax, so there's that.

Ideally I'd like to be able to use something like this

class A{
public:
  void operator()(){
    std::cout<<"A";
  }
};
class B{
public:
  void operator()(){
    std::cout<<"B";
  }
};

class C:public SeqMethod<A,B>{};

Which in this case should output "AB", and in general be suitable for composing behaviors together.


Solution

  • The easiest way to do this is with C++17's fold expressions:

    template<class ...Functor>
    struct SeqMethod:public Functor...{
    
     public:
        void operator()(){
            (Functor::operator()(),...);
        }
    };
    
    class A{
    public:
        void operator()(){
            std::cout<<"A";
        }
    };
    class B{
    public:
        void operator()(){
            std::cout<<"B";
        }
    };
    
    class C:public SeqMethod<A,B>{};
    
    int main()
    {
        C c;
        c();
        return 0;
    }
    

    Output (tested with gcc 6.2):

    AB