Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 642
violet_white Avatar asked Dec 23 '16 23:12

violet_white


People also ask

What is the use of Variadic templates?

With the variadic templates feature, you can define class or function templates that have any number (including zero) of parameters. To achieve this goal, this feature introduces a kind of parameter called parameter pack to represent a list of zero or more parameters for templates.

Is printf Variadic function?

The C printf() function is implemented as a variadic function. This noncompliant code example swaps its null-terminated byte string and integer parameters with respect to how they are specified in the format string.

What is Variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.

How do you use Variadic arguments?

In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed. The variadic function consists of at least one fixed variable and then an ellipsis(…) as the last parameter. This enables access to variadic function arguments.


1 Answers

You don't actually need any call member function in your case.
Instead you can do this in C++11/C++14:

template<class ...Functor>
struct SeqMethod:public Functor...{
  public:
  void operator()(){
      int _[] = { (Functor::operator()(), 0)... };
      return void(_);
  }
};

It follows a minimal, working example:

#include<iostream>

template<class ...Functor>
struct SeqMethod:public Functor...{
  public:
  void operator()(){
    int _[] = { (Functor::operator()(), 0)... };
    return void(_);
  }
};

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();
}
like image 151
skypjack Avatar answered Oct 13 '22 23:10

skypjack