Reputation: 506
I'm trying to write a basic TaskRunner system. A worker object does some work and returns a result. A task runner runs a worker object and returns the result of that worker. Here's what I have right now (usual warnings apply: simplified example; this may not compile):
Worker class:
template<typename ResultType>
class Worker
{
public:
virtual ~Worker() = 0;
virtual ResultType DoWork() = 0;
};
Runner class:
template<typename ResultType, typename WorkerType>
class TaskRunner
{
public:
template<typename... Args>
TaskRunner( Args&&... args )
{
Worker = std::unique_ptr<WorkerType>(new WorkerType(std::forward<Args>(args)...));
}
~TaskRunner() {}
ResultType StartWork()
{
return Worker->DoWork();
}
private:
std::unique_ptr<WorkerType> Worker;
};
I want to specialize each worker to return a concrete type:
class CustomWorker : public Worker<int>
{
public:
CustomWorker(int InNumber) : Number(InNumber) {}
~CustomWorker() {}
int DoWork() override { return Number; };
private:
int Number;
};
I have all this working, and can kick off the system with this call:
TaskRunner<int, CustomWorker> CustomTask(1);
The problem with this is that CustomWorker is tightly coupled with the return type of int. This is the only combination of template types that will work for this task. Each worker will have one, and only one return type. Therefore, I would like to be able to call:
TaskRunner<CustomWorker> CustomTask(1);
But this seems to require knowing the templated type of CustomWorker in the definition of TaskRunner::StartWork.
Something like this...
template<typename WorkerType>
class TaskRunner
{
public:
...
WorkerType::ResultType StartWork()
{
...
}
...
Is there some templating syntax / constexpr magic that could help me achieve this?
Upvotes: 0
Views: 74
Reputation: 170084
If you want to declare StartWork
as returning whatever DoWork()
returns, then you have the options of just letting the implementation figure it out in C++14
auto StartWork()
{
return Worker->DoWork();
}
Or, specify it with decltype
in C++11
auto StartWork() -> decltype(Worker->DoWork())
{
return Worker->DoWork();
}
Upvotes: 1