C++17 introduced std::invocable, but I'm wondering about C++11-only solution. My first thought is to use std::result_of.
My current code looks like this:
template<typename Function, typename... Args,
typename = typename std::result_of<Function&&(Args&&...)>::type>
int start(size_t stackSize, size_t queuedSignals, size_t signalActions,
uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function,
Args&&... args)
{
// main implementation
}
template<typename Function, typename... Args,
typename = typename std::result_of<Function&&(Args&&...)>::type>
int start(size_t stackSize, size_t queuedSignals, size_t signalActions,
uint8_t priority, Function&& function, Args&&... args)
{
return start(stackSize, queuedSignals, signalActions, priority,
SchedulingPolicy::roundRobin, std::forward<Function>(function),
std::forward<Args>(args)...);
}
template<typename Function, typename... Args,
typename = typename std::result_of<Function&&(Args&&...)>::type>
int start(size_t stackSize, uint8_t priority, Function&& function,
Args&&... args)
{
return start(stackSize, 0, 0, priority, SchedulingPolicy::roundRobin,
std::forward<Function>(function), std::forward<Args>(args)...);
}
template<typename Function, typename... Args,
typename = typename std::result_of<Function&&(Args&&...)>::type>
int start(size_t stackSize, uint8_t priority,
SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args)
{
return start(stackSize, 0, 0, priority, schedulingPolicy,
std::forward<Function>(function), std::forward<Args>(args)...);
}
There is basically one main implementation - with all possible arguments - and 3 wrappers - which don't have all arguments. I use SFINAE in the template arguments - typename = typename std::result_of<Function&&(Args&&...)>::type
- as otherwise one of the wrappers causes infinite recursion. This seems to work fine, but I did only very limited testing. However on cppreference I've read the motivation for depreciation of std::result_of
in favor of std::invoke_result
(BTW the info there is why I'm using r-value references instead of std::result_of<Function(Args...)>
), which made me wonder whether my use is correct or maybe there will be (real-life) situations where this will actually fail even though the passed arguments are correct? My use-case is passing all possible "callables": regular functions, member functions, lambdas or functors.
Aucun commentaire:
Enregistrer un commentaire