std :: enable_if一个参数是一个函数?

时间:2016-06-16 20:12:49

标签: c++ c++11

为什么以下在C ++ 11下编译? (我知道它不会链接。)我希望std::enable_if测试失败,因为1()不是函数类型。

#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;
}

3 个答案:

答案 0 :(得分:6)

FuncintArgs为空,因此Func(Args...)int(),即“()返回{{1}的函数}}”。

int返回true的任何内容都不能是by-value函数参数的类型,因此您想要做的事情并不明显。

  

我试图让委托只在is_function为a时才可调用   函数(最好是函数指针)可以应用于Func

使用表达式SFINAE。

Args...

根据您实际想做的事情,您可能需要template <typename Func, typename... Args> auto delegate(Func f, Args... args) -> decltype(f(args...), void()); std::movef

答案 1 :(得分:3)

您编写的代码将始终生效。你可能意味着std::is_function<Func>...

虽然不确定,但您似乎根本不需要enable_if,而且只需简单

就可以了。
template <class R, class... ARGS>
R delegate2(R (*fun)(ARGS...), ARGS...);

但是,如果我错了,enable_if是您案件成功的关键,那么您可以采用以下方式:

#include <type_traits>

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

void check(int);

int main(void) {
  delegate(check, 10); // << good line compiles
  delegate(10); // << this bad line does not

  return 0;
}

答案 2 :(得分:2)

基于此评论:

  

Func是一个可以应用于Args...的函数(最好是函数指针)时,我试图让委托只能被调用

您使用了错误的类型特征。要检查Func是否可以使用Args...进行调用,您需要构造一个实际上使用这些参数调用Func实例的表达式。为此,有std::result_of_t(在C ++ 14中,它变得非常友好):

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

或者,在C ++ 11中,只需用decltypedeclval写出来:

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