C++中无需指定参数类型推导lambda返回值的实现方法
回答
对于非泛型、无重载的普通lambda,是可以做到无需指定参数类型、也无需传入参数个数相关模板参数,直接推导其返回值类型的。
实现原理
普通lambda的底层会生成一个专属的闭合类型,该类型的operator()是固定签名的非模板成员函数,我们可以直接萃取该成员函数的签名信息,从中提取返回值类型,不需要额外传入参数相关的信息。
完整实现代码(C++17及以上)
#include <type_traits> #include <cstdint> // 萃取可调用对象operator()签名的traits主模板 template<typename T> struct callable_return_traits {}; // 偏特化:匹配非mutable lambda/const成员函数指针 template<typename RetType, typename ClassType, typename... ArgsType> struct callable_return_traits<RetType(ClassType::*)(ArgsType...) const> { using type = RetType; }; // 偏特化:匹配mutable lambda/非const成员函数指针 template<typename RetType, typename ClassType, typename... ArgsType> struct callable_return_traits<RetType(ClassType::*)(ArgsType...)> { using type = RetType; }; // 对外工具:传入可调用对象(支持lambda)直接获取返回值类型 template<auto callable> using get_callable_return_t = typename callable_return_traits< decltype(&std::decay_t<decltype(callable)>::operator()) >::type; int main() { // 无需指定uint8_t参数类型,直接推导返回值为bool get_callable_return_t<[](std::uint8_t const& n) -> bool { return true ^ n; }> s = true; static_assert(std::is_same_v<decltype(s), bool>); // 支持mutable lambda,推导返回值为int get_callable_return_t<[](int num) mutable { return num + 5; }> i = 10; static_assert(std::is_same_v<decltype(i), int>); return 0; }
适用限制
- 仅支持非泛型lambda:如果是带
auto参数的泛型lambda,其operator()本身是模板,不存在固定的签名,不同参数类型对应不同返回值,这种场景必须指定参数类型才能推导返回值。 - 不支持有重载
operator()的可调用对象:如果lambda(或自定义可调用对象)存在多组不同签名的operator(),无法确定要萃取哪一组的返回值,该方法不生效。
内容的提问来源于stack exchange,提问作者MindLerp
相关产品推荐
相关产品推荐

