不能。std::is_function仅对无cv限定、非引用、非指针的裸函数类型(如void()、int(double))返回true,不适用于lambda、std::function、函数对象、函数指针或成员函数指针;判断可调用性应使用std::is_invocable系列。

std::is_function 能判断 lambda 吗?
不能。std::is_function 只对「函数类型」(如 int(int))返回 true,不适用于 lambda、函数对象、std::function 或成员函数指针——它们都不是“函数类型”,而是可调用对象类型。
常见错误现象:写 std::is_function_v<decltype></decltype> 得到 false,误以为检测失败是语法错了,其实是语义不匹配。
- lambda 类型是唯一、未命名的类类型,带
operator() -
std::function<void></void>是模板类,不是函数类型 - 普通函数名(如
foo)在decltype中会退化为函数指针类型,也不是std::is_function的目标
什么时候 std::is_function 返回 true?
仅当类型是「无 cv 限定、非引用、非指针的函数类型」时成立。比如 void()、int(double, char*) 这种裸函数签名。
实操建议:通常只在模板元编程中配合 decltype + 函数声明(非调用)使用,例如检测某个符号是否是函数声明而非变量:
立即学习“C++免费学习笔记(深入)”;
void func(); static_assert(std::is_function_v<decltype(func)>); // ✅ true int var; static_assert(!std::is_function_v<decltype(var)>); // ✅ false
- 加
&或*就失效:decltype(func)&是函数引用,decltype(func)*是函数指针,std::is_function全部返回false - 成员函数类型(如
int (A::*)())也不算,它属于std::is_member_function_pointer的范畴 - C++17 起支持
std::is_function_v,避免写::value
想统一判断“能不能调用”,该用什么?
用 std::is_invocable 系列,而不是 std::is_function。它专为可调用性设计,覆盖函数、lambda、重载了 operator() 的类、绑定表达式等。
使用场景:写泛型函数时,需提前约束参数是否可被某方式调用,比如实现一个只接受能 () 的回调:
template<typename F, typename... Args>
auto call_if_invocable(F&& f, Args&&... args)
-> std::enable_if_t<std::is_invocable_v<F, Args...>, decltype(f(args...))> {
return f(std::forward<Args>(args)...);
}-
std::is_invocable检查能否调用(不关心返回值) -
std::is_invocable_r<r></r>检查能否以 R 类型接收返回值 -
std::is_nothrow_invocable还能检查是否noexcept - 注意:它不区分“函数”和“仿函数”,这是有意为之的设计取舍
std::is_function 在模板偏特化里容易踩什么坑?
直接拿 std::is_function 做 SFINAE 分支,很容易漏掉函数指针或引用——而现实中传进来的几乎全是这些。
比如想给“函数类型”和“其他类型”写不同实现,但用户传了 void(*)(),分支就走错:
template<typename T> struct handler { /* 默认 */ };
template<typename T> struct handler<T, std::enable_if_t<std::is_function_v<T>>> { /* 仅函数类型 */ };- 传
void()✅ 匹配偏特化 - 传
void(*)()❌ 走默认,因为是指针类型 - 传
decltype(foo)(foo是函数名)→ 实际是函数指针,同样不匹配 - 更稳妥的做法是先用
std::remove_pointer_t和std::remove_reference_t归一化,再判断
真正用到 std::is_function 的地方其实很少,多数时候你真正想问的是:“它能被 () 调用吗?”——那就别绕弯子去碰这个狭义类型特征。









