Variadic Template Functor Call

Поэтому я пытался использовать шаблоны с переменным числом аргументов для составления объектов из более удобных подтипов, но у меня возникают проблемы с тем, чтобы заставить его делать именно то, что я хочу.

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...>();
  }
};

Это неверный синтаксис, так что есть.

В идеале я хотел бы иметь возможность использовать что-то вроде этого

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

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

Который в этом случае должен выводить "AB" и в целом быть подходящим для составления поведения вместе.

2 ответа

Решение

Самый простой способ сделать это с помощью выражений свёртывания в C++17:

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;
}

Выход (протестировано с gcc 6.2):

AB

Вам на самом деле не нужно call функция-член в вашем случае.
Вместо этого вы можете сделать это в C++11/C++14:

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

Следует минимальный рабочий пример:

#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();
}
Другие вопросы по тегам