Reputation: 164
I have the two following functions:
template<class F, class... Args>
auto runAt(F&& function, const std::chrono::steady_clock::time_point& timePoint, Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type> {
using return_type = typename std::result_of<F(Args...)>::type;
std::future<return_type> futureResult;
auto packagedTask = std::make_shared<std::packaged_task<return_type()> >
(std::bind(std::forward<F>(function), std::forward<Args>(args)...));
futureResult = packagedTask->get_future();
this->addTask(Task([this, packagedTask]() {
(*packagedTask)();
}), timePoint);
return futureResult;
}
void runAt(const Task& task,
const std::chrono::steady_clock::time_point& timePoint);
In my main.cpp file, I created a Task object, assigned a function to it and pushed it into my scheduler. runAt are scheduler's functions.
This is the code:
... // Task initialization
scheduler.runAt(task, std::chrono::steady_clock::now());
The problem is that the templated function is called instead of the one taking a Task as parameter. I understand that both functions are valid since the first parameter is templated and the variadic argument object is empty.
I have two questions:
1) How to call the second method (consider that the return types are not the same)
2) Not very important but I'm curious to know how this does not fail during the compilation
auto packagedTask = std::make_shared<std::packaged_task<return_type()> >
(std::bind(std::forward<F>(function), std::forward<Args>(args)...));
Upvotes: 3
Views: 249
Reputation: 137310
1) How to call the second method (consider that the return types are not the same)
Constrain the first one.
template<class F, class... Args,
class = std::enable_if_t<!std::is_same<std::decay_t<F>, Task>{}>>
auto runAt(F&& function, const std::chrono::steady_clock::time_point& timePoint,
Args&&... args)
-> std::future<typename std::result_of<F(Args...)>::type> {
/* ... */
}
Incidentally,
auto packagedTask = std::make_shared<std::packaged_task<return_type()> >
(std::bind(std::forward<F>(function), std::forward<Args>(args)...));
is incorrect. bind
does special handling for nested binds and placeholders, which you don't want, since you computed the return type as typename std::result_of<F(Args...)>::type
.
Upvotes: 5