用于检查模板参数是否“可调用”的C ++ 11方法

时间:2019-07-01 09:29:57

标签: c++ c++11 templates sfinae

C ++ 17引入了std::invocable,但我想知道仅C ++ 11的解决方案。我的第一个想法是使用std::result_of

我当前的代码如下(SchedulingPolicyenum class):

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)...);
}

基本上有一个主要实现-具有所有可能的参数-和3个包装器-它们没有所有参数。我在模板参数-typename = typename std::result_of<Function&&(Args&&...)>::type中使用SFINAE-否则,其中一个包装器将导致无限递归。这似乎工作正常,但我只进行了非常有限的测试。但是在cppreference上,我已经读到std::result_of贬值的动机,而倾向于std::invoke_result(顺便说一下,这就是为什么我使用r值引用而不是std::result_of<Function(Args...)>的原因)让我想知道我的使用是否正确,或者在某些情况下,即使传递的参数正确无误,这实际上也会失败?我的用例是传递所有可能的“可调用对象”:常规函数,成员函数,lambda或函子。

0 个答案:

没有答案