为什么以下在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;
}
答案 0 :(得分:6)
Func
为int
,Args
为空,因此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::move
和f
。
答案 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中,只需用decltype
和declval
写出来:
template <typename Func, typename... Args,
class R = std::declval<Func>()(std::declval<Args>()...)>
R delegate(Func, Args...);