C++11中Lambda函数的使用及函数指针适配问题
问题原因
你遇到的核心问题是:带捕获(比如this)的Lambda表达式无法隐式转换为普通函数指针。doSomething的第三个参数是普通函数指针类型string(*lookUpFunction)(string a, int b),这类指针只能指向无状态的可调用对象(比如普通全局函数、静态成员函数,或者无捕获的Lambda)。而你用[this]捕获了当前对象,Lambda就带上了状态,自然无法匹配普通函数指针类型。
解决方案
方案一:修改doSomething的参数类型(推荐)
把参数从普通函数指针改成std::function<string(string, int),这样就能兼容所有符合签名的可调用对象,包括带捕获的Lambda、绑定了对象的成员函数等。修改后的代码如下:
#include <functional> // 必须包含该头文件 int doSomething(string a, int b, std::function<string(string, int)> lookUpFunction) { return lookUpFunction(a,b).length(); } // 调用部分无需改动,原Lambda可直接使用 class x { DataBase* db; public: int myFunc(); }; int x::myFunc() { return doSomething("a",1,[this](string a, int b)->string { return db->someFuncThatTakesStringAndInt(a,b); }); }
方案二:不修改doSomething的临时 workaround(不推荐)
如果无法修改doSomething的定义,只能通过引入全局状态的方式绕开,但这种方式线程不安全,仅适合简单场景:
// 全局变量,注意多线程环境下会出问题 x* global_x_instance = nullptr; string wrapperFunc(string a, int b) { return global_x_instance->db->someFuncThatTakesStringAndInt(a,b); } int x::myFunc() { global_x_instance = this; return doSomething("a",1, wrapperFunc); }
也可以把包装函数改成类的静态成员,缩小全局状态的作用域:
class x { DataBase* db; static x* current_instance; static string wrapperFunc(string a, int b) { return current_instance->db->someFuncThatTakesStringAndInt(a,b); } public: int myFunc(); }; x* x::current_instance = nullptr; int x::myFunc() { current_instance = this; return doSomething("a",1, x::wrapperFunc); }
内容的提问来源于stack exchange,提问作者Matthew Cornelisse
相关产品推荐
相关产品推荐

