如何判断一个类型是否为lambda类型,是否有类似std::is_function的判断方式?
C++判断类型是否为lambda类型的实现方案
C++标准库目前没有提供类似std::is_function的、可以直接判断类型是否为lambda的专用工具。你之前使用std::is_invocable无法满足需求是正常的,该模板的定位是校验指定可调用对象能否以给定参数列表触发调用,和目标类型是否为lambda没有直接关联。
核心原因
lambda本质是编译器生成的匿名闭包类型,每一个lambda表达式都会生成全局唯一的独立类型,该类型只会在编译期由编译器生成,标准层面没有为lambda类型设置专属的类型标记,它和用户手写的重载了operator()的仿函数类型没有本质区别。
通用实现方案
如果你不需要严格区分lambda和手写仿函数,仅需要判断目标类型是否是可直接调用的闭包类型(覆盖所有有捕获/无捕获lambda场景),可以借助SFINAE自定义类型特性实现:
#include <type_traits> // 主模板默认判定为非lambda template<typename T, typename = void> struct is_lambda : std::false_type {}; // 特化匹配存在operator()的非函数、非指针类型 template<typename T> struct is_lambda<T, std::void_t<decltype(&T::operator())>> : std::bool_constant< !std::is_function_v<T> && !std::is_pointer_v<T> && !std::is_member_function_pointer_v<T> > {}; // 便捷使用的变量模板 template<typename T> constexpr bool is_lambda_v = is_lambda<T>::value;
实现效果示例
int main() { // 无捕获lambda auto lam1 = [](){}; // 有捕获lambda auto lam2 = [val = 10](){ return val; }; // 普通函数指针 void (*func_ptr)() = [](){}; // 手写仿函数 struct CustomFunctor { void operator()() {} }; static_assert(is_lambda_v<decltype(lam1)>); // 判定成立 static_assert(is_lambda_v<decltype(lam2)>); // 判定成立 static_assert(!is_lambda_v<decltype(func_ptr)>); // 判定成立 static_assert(is_lambda_v<CustomFunctor>); // 判定成立:标准层面无法区分手写仿函数与lambda }
严格区分lambda与手写仿函数的方案(非可移植)
如果必须严格区分二者,只能依赖编译器内置的调试信息接口实现:
- GCC/Clang可以通过
__PRETTY_FUNCTION__获取类型名,判断其中是否包含<lambda特征串 - MSVC可以通过
__FUNCSIG__获取类型名,判断其中是否包含lambda特征串
该方案依赖编译器实现,无法跨编译器兼容。
内容的提问来源于stack exchange,提问作者VeNToR
相关产品推荐
相关产品推荐

