std::is_function无法将模板参数识别为函数。

12

我正在将一个指向函数的指针传递到一个函数模板中:

int f(int a) { return a+1; }

template<typename F>
void use(F f) {
    static_assert(std::is_function<F>::value, "Function required"); 
}

int main() {
    use(&f); // Plain f does not work either.
}

但是模板参数F没有被is_function识别为函数,因此静态断言失败。编译器错误消息显示F是指向函数的指针int(*)(int)。为什么会出现这种情况?在这种情况下,我如何识别函数或指向函数的指针?

1个回答

15

F是一个指向函数的指针(无论你传递 f 还是 &f)。因此,请移除指针:

std::is_function<typename std::remove_pointer<F>::type>::value

(具有讽刺意味的是,std::is_function<std::function<FT>> == false ;-)

2
我讨厌隐式转换 :( - Matthieu M.
5
具有讽刺意味的是,"std::is_function<std::function<FT>> == false";也许对于未来的标准来说,一个"std::is_callable"可能是个好主意,因为"std::is_function"甚至不能用于lambda表达式,只能用于简单的函数(而在现代C++中,每个可调用对象都是函数的时间已经过去了)。 - Christian Rau
1
@ChristianRau std::is_function 是主要的分类特征之一。is_callable 或类似的东西将完全服务于不同的目的。 - Luc Danton
@LucDanton 当然。没有人会质疑 std::is_function 的价值,它非常适用于像 std::is_array (该函数也不应该std::array 返回 true) 或 std::is_class 等情景中。但是,在其他相当高级别的特性(如已经提议的std::is_swappable以及迫切需要的(尽管我不确定是否已经提出)std::is_hashable)中增加一个额外的 std::is_callable 将是个好主意,并且与其他高级别特性保持一致。 - Christian Rau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接