C++ 如果参数是函数,是否启用?

C++ 如果参数是函数,是否启用?,c++,c++11,C++,C++11,为什么下面的代码在C++11下编译?我知道它不会链接。由于1不是函数类型,因此如果测试失败,我希望std::enable_会失败 #include <type_traits> template <typename Func, typename... Args> typename std::enable_if<std::is_function<Func(Args...)>::value>::type delegate(Func, Args.

为什么下面的代码在C++11下编译?我知道它不会链接。由于1不是函数类型,因此如果测试失败,我希望std::enable_会失败

#include <type_traits>

template <typename Func, typename... Args>
typename std::enable_if<std::is_function<Func(Args...)>::value>::type
    delegate(Func, Args...);

int main(void) {
  delegate(1); // << Why does this line compile?
  return 0;
}
Func为int,Args为空,因此FuncArgs。。。是int,即返回int的函数

任何函数返回true的对象都不能是by-value函数参数的类型,因此不清楚您想要做什么

我试图使委托仅在Func为 函数最好是可以应用于参数的函数指针

使用表达式SFINAE

template <typename Func, typename... Args>
auto delegate(Func f, Args... args) -> decltype(f(args...), void());
根据实际需要,可能需要std::move f和args。

Func为int,args为空,因此FuncArgs。。。是int,即返回int的函数

任何函数返回true的对象都不能是by-value函数参数的类型,因此不清楚您想要做什么

我试图使委托仅在Func为 函数最好是可以应用于参数的函数指针

使用表达式SFINAE

template <typename Func, typename... Args>
auto delegate(Func f, Args... args) -> decltype(f(args...), void());

根据实际需要,您可能需要std::move f和args。

您编写的代码将始终生成true。你可能是指std::is_函数

虽然不确定,但似乎您根本不需要enable_,最好使用一个简单的

template <class R, class... ARGS>
R delegate2(R (*fun)(ARGS...), ARGS...);

您编写的代码将始终生成true。你可能是指std::is_函数

虽然不确定,但似乎您根本不需要enable_,最好使用一个简单的

template <class R, class... ARGS>
R delegate2(R (*fun)(ARGS...), ARGS...);
根据这一评论:

我试图使委托仅在Func是一个函数(最好是可以应用于参数的函数指针)时才可调用

你使用了错误的类型特征。若要检查Func是否可使用Args…调用,需要构造一个表达式,该表达式将实际使用这些参数调用Func的实例。因此,在C++14中有std::result_of_t,它变得对SFINAE友好:

template <typename Func, typename... Args,
    class R = std::result_of_t<Func(Args...)>>
R delegate(Func, Args...);
根据这一评论:

我试图使委托仅在Func是一个函数(最好是可以应用于参数的函数指针)时才可调用

你使用了错误的类型特征。若要检查Func是否可使用Args…调用,需要构造一个表达式,该表达式将实际使用这些参数调用Func的实例。因此,在C++14中有std::result_of_t,它变得对SFINAE友好:

template <typename Func, typename... Args,
    class R = std::result_of_t<Func(Args...)>>
R delegate(Func, Args...);

你愿意写下如何正确使用它吗?或者给我指一个链接?你到底想说什么?我想让委托只在Func是函数时才可调用,最好是可以应用于Args的函数指针。。。。我想我想要Func*作为第一个参数的类型。你愿意写下如何正确使用它吗?或者给我指一个链接?你到底想说什么?我想让委托只在Func是函数时才可调用,最好是可以应用于Args的函数指针。。。。我想我想要Func*作为第一个参数的类型。@T.C.,请参阅我的更新答案-它将与正确的检查调用一起工作。@T.C.,我很久以前就不再问为什么了。无论如何,我已经将代码更新到了一个更好的版本。我的第一次尝试类似于delegate2。不幸的是,它要求类型完全匹配——因此,如果fun需要很长时间,则不能传递int-literal或其他类型,但必须显式强制转换。我希望找到一个代理调用来进行转换或以其他方式帮助类型匹配。@oconnor0,有意义。@T.C.,请参阅我的更新答案-它将与适当的检查调用一起工作。@T.C.,我很久以前就不再问为什么了。无论如何,我已经将代码更新到了一个更好的版本。我的第一次尝试类似于delegate2。不幸的是,它要求类型完全匹配——因此,如果fun需要很长时间,则不能传递int-literal或其他类型,但必须显式强制转换。我希望找到一个委托调用来进行转换或帮助类型匹配。@oconnor0,有意义。result_of是错误的,除非您愿意并将使用INVOKE的全部功能。result_of是错误的,除非您愿意并将使用INVOKE的全部功能。小注释-我可以想象OP希望从委托返回函数返回值。很可能是decltypefargs。。。;当然,这纯粹是我的猜测。我实际上想让代表返回void。不过,上述方法非常有效,谢谢出于好奇,为什么它是空的?因为decltype需要一个对象来解构它的类型。void用作void类型的对象。但是出于好奇,你为什么想要sfinae呢?下面的答案中显示的普通函数有什么问题?小注释-我想象OP希望从委托返回函数返回值。很可能是decltypefargs。。。;当然,这纯粹是我的猜测。我实际上想让代表返回void。以上工作如下: 尽管如此,谢谢出于好奇,为什么它是空的?因为decltype需要一个对象来解构它的类型。void用作void类型的对象。但是出于好奇,你为什么想要sfinae呢?下面我的答案中显示的普通函数有什么问题?