【问题标题】:Sfinae on function with either zero or one parameter具有零或一个参数的函数
【发布时间】:2014-04-01 06:57:36
【问题描述】:

考虑以下两个声明:

template <class Function, 
          class = typename std::enable_if</*Function has zero argument*/>::type>
void apply(Function&& function);
template <class Function, 
          class... Dummy,
          class = typename std::enable_if</*Function has one argument*/>::type,
          class = typename std::enable_if<sizeof...(Dummy) == 0>::type>
void apply(Function&& function, Dummy...);

当函数有零个或一个参数(不管参数的类型)时,我应该在第一种和第二种情况下在std::enable_if 中输入什么来约束重载?

【问题讨论】:

  • 首先,我不建议这样使用默认模板 arg。通常你不知道函数是否可以用一个参数调用,而不管类型如何。在某些情况下,可以转换为任何内容的虚拟类型可能会起作用,但如果函数使用 SFINAE,则不会。
  • 为什么你会关心一个函数是否可以用一个参数调用但你不知道参数的类型?如果你不知道参数的类型,你不可能调用它。您可以调用它的唯一场景是您知道参数类型的场景。

标签: c++ c++11 metaprogramming overloading sfinae


【解决方案1】:

以下特征可能会对您有所帮助:

#include <type_traits>
#include <functional>

template <typename T>
struct arity : public arity<decltype(&T::operator())> {};

template <typename C, typename Ret, typename... Args>
struct arity<Ret(C::*)(Args...) const> :
    std::integral_constant<std::size_t, sizeof...(Args)>
{
};

// Do the same for other (11) combination of volatile, const, reference method.

// function pointer
template<class R, class... Args>
struct arity<R(*)(Args...)> : public arity<R(Args...)>
{};

template<class R, class... Args>
struct arity<R(Args...)> : std::integral_constant<std::size_t, sizeof...(Args)>
{
};

然后

template <class Function,
          class = typename std::enable_if<arity<typename std::remove_reference<Function>::type>::value == 0>::type>
void apply(Function&& function);

【讨论】:

  • 函数对象呢?
  • 您可以完成仿函数类(使用operator ())和std::function`的特征。
  • FWIW,有 has_call 特征(注意:不是 Boost 的一部分)
  • 这是多么没用 :S 如果你打算将自己限制在函数指针上,只需这样做:template &lt;class R&gt; void apply(R(*function)()); template &lt;class R, class Arg0, class... Args&gt; void apply(R(*function)(Arg0, Args...)); 如果你要正确地做到这一点并支持各种可调用类型,这个 "功能特征”的废话永远都行不通。
  • @R.MartinhoFernandes:给定的链接为某些成员 operator () 完成了此操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多