对模板化对象的矢量中的每个元素调用模板化方法

时间:2016-12-05 21:50:51

标签: c++ c++11 templates c++14

我有一系列任务对象,我想将它们链接在一起,这样一个任务的输出就是下一个任务的输入。

template <typename Input, typename Output> class Task {
public:
  std::function<Output(Input)> func;

  Task(std::function<Output(Input)> func) : func(func){};
  Output run(const Input& input) { return func(input); }
};

太好了,现在我可以将一些任务联系在一起了。

#include <iostream>
#include "Task.h"

int main() {
  auto func1 = [](int i) {
    return i + 1;
  };
  auto func2 = [](std::string i) {
    return stoi(i);
  };

  Task<int, int> task1(func1);
  Task<std::string, int> task2(func2);

  std::cout << task1.run(task2.run("1"));
  return 0;
}

但是现在,我想将任务放在TaskList容器中,这样我就不需要对这些任务链进行硬编码。 API可能如下所示:

class TaskList {
public:
  std::vector<ITask> tasks;

  void append(ITask task) { tasks.push_back(task); }
  void run() { // Run all tasks }
};

其中ITask是各种Task<Input, Output>类型的基类。我怎么写这样的ITaskTaskList类?有很多方法可以改变引入类型的方法(例如,Task构造函数,run方法),但我还没有找到一种方法可以推广到TaskList

这种做法完全错了吗?或者我正在尝试做糟糕的设计?

1 个答案:

答案 0 :(得分:0)

如何使用递归和模板特化而不是std::vector

以下应该是一个工作示例

#include <functional>
#include <iostream>

template <typename, typename ...>
class TaskList;

template <typename First>
class TaskList<First>
 {
   public:
      TaskList () 
       { }

      First run (First const & firstVal) const
       { return firstVal; }
 };

template <typename Output, typename Input, typename ... Prevs>
class TaskList<Output, Input, Prevs...>
 {
   private:
      std::function<Output(Input)> const  head;
      TaskList<Input, Prevs...>    const  tail;

   public:
      template <typename ... Funcs>
      TaskList (std::function<Output(Input)> const & f0,
                Funcs const & ... funcsPre)
         : head {f0}, tail {funcsPre...}
       { }

      template <typename T>
      Output run (T const & firstArg) const
       { return head(tail.run(firstArg)); }
 };

int main ()
 {
   auto func0 = [](int i) { return long(i << 1); };
   auto func1 = [](int i) { return i + 1; };
   auto func2 = [](std::string i) { return stoi(i); };

   TaskList<long, int, int, std::string> taskL012(func0, func1, func2);

   std::cout << taskL012.run("1") << std::endl; // print 4
 }