My code consists of 2 files: main.cpp
and utils.hpp
. The contents of those files are given below:
utils.hpp
#ifndef UTILITY_HPP
#define UTILITY_HPP
#include <iostream>
#include <thread>
#include <future>
#include <functional>
#include <chrono>
using std::chrono::milliseconds;
class CallableStoppableTask {
std::promise<void> exit_signal;
std::future<void> future_obj;
public:
CallableStoppableTask() : future_obj(exit_signal.get_future()) {}
CallableStoppableTask(const CallableStoppableTask&) = delete;
CallableStoppableTask& operator=(const CallableStoppableTask&) = delete;
virtual void run() = 0;
void operator()() { run(); }
bool is_stop_requested(int timeout_milliseconds = 0) const {
return (future_obj.wait_for(milliseconds(timeout_milliseconds)) == std::future_status::ready);
}
void request_stop() { exit_signal.set_value(); }
};
struct Car {
int model;
int price;
explicit Car(const int& arg_model = -1, const int& arg_price = -1)
: model(arg_model), price(arg_price) {}
};
class CallableSampleTask : public CallableStoppableTask {
CallableSampleTask(const CallableSampleTask&) = delete;
CallableSampleTask& operator=(const CallableSampleTask&) = delete;
void run() override {
std::cout << "Running Some Car Sample Task.. " << std::endl;
}
public:
CallableSampleTask(const Car& arg_car = Car()) {}
};
#endif
To implement a task that can be interrupted we inherit the CallableStoppableTask
for eg., CallableSampleTask
.
The contents of main.cpp
are:
#include "utils.hpp"
#include <iostream>
#include <array>
#include <future>
#include <memory>
#define NUM_TASK 5
static std::array<std::unique_ptr<CallableSampleTask>, NUM_TASK> ar_uptr_task;
int main() {
std::unique_ptr<CallableSampleTask> f = std::move(std::make_unique<CallableSampleTask>());
(*f.get())(); // COMPILE TIME ERROR: what is the error in this?
ar_uptr_task.fill(std::move(std::make_unique<CallableSampleTask>()));
for (int i = 0; i < NUM_TASK; i++) {
// I want to do something like this. COMPILE TIME ERROR
auto discard_ret = std::async(std::launch::async, (*ar_uptr_task[i].get()));
}
std::cout << "Hello, World!" << std::endl;
return 0;
}
The above throws a very big COMPILE TIME ERROR. I have commented the lines in main.cpp
file which throws the error.
I am using the following command to compile:
g++ -std=c++17 -pthread main.cpp
Any idea where and what I am going wrong?
PS: Please enlighten me with great C++ concepts if I am missing something.
I can't post the error because it is exceeding the stackoverflow limit. Here is the github link: https://github.com/KishoreKaushal/CallableObjects
This line is fine
(*f.get())(); // COMPILE TIME ERROR: what is the error in this?
but shorter version
(*f)();
is better.
ar_uptr_task.fill(std::move(std::make_unique<CallableSampleTask>()));
doesn't make any sense. fill
takes source as const object, how do you want apply move operation on const source object [also you want to move source object N-times, but first move operation leaves source object in empty state] ?
Can be replaced by:
for (int i = 0; i < 5; ++i)
ar_uptr_task[i] = std::make_unique<CallableSampleTask>();
If you want pass functor to async
function, wrap it in reference_wrapper
by using ref
:
for (int i = 0; i < NUM_TASK; i++) {
auto discard_ret = std::async(std::launch::async, std::ref(*ar_uptr_task[i]));
}