C++ 具有零或一个参数的函数上的Sfinae

C++ 具有零或一个参数的函数上的Sfinae,c++,c++11,metaprogramming,overloading,sfinae,C++,C++11,Metaprogramming,Overloading,Sfinae,考虑以下两项声明: template <class Function, class = typename std::enable_if</*Function has zero argument*/>::type> void apply(Function&& function); template <class Function, class... Dummy, class = typen

考虑以下两项声明:

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_中放置什么来约束重载

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

#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)>
{
};
#包括
#包括
模板
结构性:公共性{};
模板
结构:
积分常数
{
};
//对volatile、const和reference方法的其他(11)组合也进行同样的操作。
//函数指针
模板
结构性:公共性
{};
模板
结构:std::积分常数
{
};
然后

template <class Function,
          class = typename std::enable_if<arity<typename std::remove_reference<Function>::type>::value == 0>::type>
void apply(Function&& function);
模板
无效申请(职能和职能);

关于函数对象呢?你可以用
操作符()和std::function()来完成functor类的trait。FWIW,有trait(注意:不是Boost的一部分)这是多么无用:如果你想把自己限制在函数指针上,只需做:
模板void apply(R(*function)();模板无效应用(R(*函数)(Arg0,Args…)
如果要正确执行此操作并支持所有类型的可调用类型,这种“函数特性”的废话永远不会起作用。@R.MartinhoFernandes:给定的链接为某些成员
操作符()
完成此操作。首先,我不建议以这种方式使用默认模板arg。一般来说,不管函数的类型是什么,你都不知道是否可以用一个参数调用函数。在某些情况下,转换为任何内容的伪类型都可能有效,但如果函数使用SFINAE,则无效。如果函数可以使用一个参数调用,但您不知道该参数的类型,您为什么会在意呢?如果您不知道参数的类型,就不可能调用它。您可以调用它的唯一场景是您知道参数类型的场景。