1

I am trying to make a basic synchronous task scheduler in C++ for my application.The way I am thinking to do this is to treat every task as a Task object, and then the TaskScheduler can operate on them rather than handling multiple types.

class Task {
public:
    Task( ... ? /* some sort of callback function stored in the task which is called at a later time*/) {}

    virtual void Execute() = 0;
}

The Task will be responsible for storing what happens on each task and I am thinking to pass a function to either the constructor of the Task object, or the execution but here is where I am stuck. For example if I had two tasks IntegerTask : Task and StringTask : Task and their callback functions looked like func(int, int, int) and func(std::string) respectively.

How can I pass these functions to the base task when the arguments might differ in lengths and the types of each parameter may change depending on which task has been created?

I don't want the TaskScheduler to be coupled with anything outside of its class, as such it should be able to operate on its own without any dependencies. Please ask if there is any clarification needed, I tried to explain as best as I could. Is this even possible in C++ or is there a better solution for what I am trying to achieve?

3
  • @MatthieuBrucher Thank you for the reply. So they're not normally supposed to run with any parameters? Commented Jan 4, 2019 at 11:05
  • @MatthieuBrucher Oh wow, that's exactly what I was looking for then! I'll give this a try and see how it works out Commented Jan 4, 2019 at 11:14
  • Why do you want to pass a function with unknown parameter list? You cannot call it! Commented Jan 4, 2019 at 12:00

1 Answer 1

4

Instead of providing a complex class with virtual calls, use std::function<void()> in association with lambdas:

class Task
{
    std::function<void()> task;
public:
    Task(std::function<void()> task):task(std::move(task)){}

    void execute() {task();}
};

Then to create a task with different "types", just do:

std::string foo = "foo";

Task task1([=]() {  foo.size(); } );
task1.execute();

int bar = 0;

Task task2([=]() {  bar; } );
task2.execute();

Be aware that I'm using [=] here. This copies the required values int he lambdas, so that I don't have to deal with object lifetime. If you know the object always exists, you can use [&] or a combination of the two.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.