如何在C++ Lambda中捕获函数?报错及同类方案疑问
Lambda捕获函数的问题解析与解决方案
错误原因
Lambda的捕获列表只能捕获变量(包括局部变量、类成员变量、静态变量等),而isVowel是函数标识符,不属于变量范畴,直接写[isVowel]会触发编译错误error: capture of non-variable ‘bool isVowel(char)’。
修复方案
方案1:直接调用全局函数(最简单)
由于isVowel是全局函数,Lambda内部可以直接访问,不需要捕获:
#include <iostream> #include <algorithm> #include <set> #include <list> using namespace std; bool isVowel(char c){ string myVowels{"aeiouäöü"}; set<char> vowels(myVowels.begin(), myVowels.end()); return (vowels.find(c) != vowels.end()); } int main(){ list<char> myCha{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}; int cha[]= {'A', 'B', 'C'}; auto iter = adjacent_find(myCha.begin(), myCha.end(), [](char a, char b){ return isVowel(a) == isVowel(b); }); if (iter != myCha.end()) cout << *iter; }
方案2:捕获函数指针(适用于非全局函数场景)
如果函数不是全局的,或者需要显式捕获函数的指针,可以通过初始化捕获将函数转换为指针变量后捕获:
auto iter = adjacent_find(myCha.begin(), myCha.end(), [func = isVowel](char a, char b){ return func(a) == func(b); });
这里func = isVowel会将函数隐式转换为函数指针,再把这个指针作为变量捕获到Lambda的闭包中。
为什么函数指针方案能生效?
Lambda捕获列表的核心要求是捕获变量,函数指针本质是存储函数内存地址的指针类型变量(或可作为右值的指针值)。当通过初始化捕获将函数转换为指针时,实际上是把一个符合捕获规则的变量(指针)存入Lambda中,而非直接捕获函数标识符,因此编译器会允许这种操作。
内容的提问来源于stack exchange,提问作者Willi
相关产品推荐
相关产品推荐

