lundi 5 décembre 2016

Call templated method on each element in a vector of templated objects

I have a sequence of task objects that I'd like to chain together such that the output from one task is the input to the next.

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

Great, now I can chain some tasks together.

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

But now, I'd like to put tasks in a TaskList container so I don't need to hardcode these chains of tasks. The API might look as follows:

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

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

Where ITask is a base class for the various Task<Input, Output> types. How might I write such ITask and TaskList classes? There are many ways to shuffle where the types get introduced (e.g., Task constructor, run method), but I haven't found a way to generalize to TaskList.

Is this approach totally wrong? Or is what I'm trying to do bad design? Any help would be much appreciated!

Aucun commentaire:

Enregistrer un commentaire