如何获取无捕获模板lambda的operator()的函数指针
问题根因
无捕获模板lambda的operator()是默认带const修饰的类成员函数,直接取成员函数地址得到的是成员函数指针,类型和普通函数指针不兼容。两类错误对应原因如下:
- 取实例的
operator()地址:得到的是绑定到对象的成员函数表达式,C++不允许将这类表达式直接取地址转为普通函数指针,因此报绑定成员函数表达式上的非法操作相关错误。 - 取类作用域下的
operator()地址:得到的是unsigned (LambdaType::*)(unsigned) const类型的成员函数指针,和目标普通函数指针unsigned (*)(unsigned)类型完全不匹配,因此报类型转换失败。
可用解决方案
方案1:利用无捕获lambda的隐式转换特性
无捕获lambda支持隐式转换为对应签名的普通函数指针,可通过包装一层极简无捕获lambda拿到特化后的函数指针:
int main() { static auto l = []<bool a, bool b>( unsigned c ) -> unsigned { return (unsigned)a + b + c; }; using fn_t = unsigned (*)( unsigned ); // 加号+用于强制触发无捕获lambda到函数指针的转换 fn_t fn = +[](unsigned c) { return l.operator()<true, false>(c); }; }
方案2:显式触发转换
直接对特化后的operator()做类型转换,显式转为目标函数指针类型:
int main() { static auto l = []<bool a, bool b>( unsigned c ) -> unsigned { return (unsigned)a + b + c; }; using fn_t = unsigned (*)( unsigned ); fn_t fn = static_cast<fn_t>(l.template operator()<true, false>); }
以上两种方案在Clang 12、MSVC 2019及更高版本均可以正常编译运行。
内容的提问来源于stack exchange,提问作者Bonita Montero
相关产品推荐
相关产品推荐

