C++ 使用[]和[this]时lambda的类型不同
我有一个类db_接口。并定义了lambda类型:C++ 使用[]和[this]时lambda的类型不同,c++,c++11,lambda,C++,C++11,Lambda,我有一个类db_接口。并定义了lambda类型: typedef void (*db_interface_lambda)(); 当我在类中以这样的方式创建lambda时:[](){/*做某事*/},它的类型很好(db_interface_lambda),但当我使用[this](){/*做某事*/}时,编译器开始对我大喊大叫 cannot convert ‘db_interface::db_interface(std::ifstream&)::<lambda()>’ to ‘
typedef void (*db_interface_lambda)();
当我在类中以这样的方式创建lambda时:[](){/*做某事*/}
,它的类型很好(db_interface_lambda),但当我使用[this](){/*做某事*/}
时,编译器开始对我大喊大叫
cannot convert ‘db_interface::db_interface(std::ifstream&)::<lambda()>’ to ‘std::map<std::basic_string<char>, void (*)()>::mapped_type {aka void (*)()}’ in assignment
无法在赋值中将'db_接口::db_接口(std::ifstream&)::'转换为'std::map::mapped_类型{aka void(*)()()}'
如何解决这个问题?正确的类型是什么?不捕获任何内容的lambda本质上是自由函数,因此可以转换为普通函数指针 捕获的lambda本质上是完整的类,它们不能简单地转换为自由函数指针。(捕获lambda实际上是与谓词函子类基本相同的,在使用lambdas之前,您将在C++中编写)。
lambda的任何一个版本都可以转换为
std::function
,这就是映射的映射类型。因为lambda只有在不捕获任何内容时才可以隐式转换为函数指针
§5.1.2[expr.prim.lambda]p6
没有lambda捕获的lambda表达式的闭包类型([]
为空)具有公共非虚拟非显式常量转换函数,指向与闭包类型的函数调用运算符具有相同参数和返回类型的函数指针
顺便说一句,您需要定义的是函数指针,而不是lambda类型。Lambda表达式具有唯一的、未命名的非统一类类型。你不能说出他们的名字
§5.1.2[expr.prim.lambda]p3
lambda表达式的类型(也是闭包对象的类型)是唯一的、未命名的非统一类类型
您试图调用需要函数指针的对象。无捕获lambda可以自动转换为函数指针,但一旦您写入
[this]
它就不再是无捕获的-您正在捕获this
,因此这是一个错误
解决方案是将类型更改为
std::function
,而不是指向函数的指针std::function
删除它“包装”的“functor”类型,这样您仍然可以传递函数指针以及带有捕获的lamba。无状态函数和自由函数是不同的,struct x{void operator()({})
显然是无状态的,不是一个自由函数,而是一个函子类。正如@awoodland指出的,不捕获的lambda可以转换为具有类似签名的自由函数,但这远远不是本质上的自由函数。lambda本质上是一个函子(函数类)@DavidRodríguez dribeas:嗯,我有点手舞足蹈,但也就是说,任何合理的优化编译器都会将你的x()
作为一个自由函数来实现——只是在x
的情况下,你无法通过语言访问它,在不捕获lambda的情况下,您或多或少会这样做(即,您可以访问转换,但是转换是在引擎盖下实现的——可能是无操作)。“并定义了lambda类型:typedef void(*db_interface_lambda)(;
”,这不是lambda类型,这是函数指针类型。正如大家所建议的,最好的解决方案是使用std::function<代码>类型定义标准::函数db\u接口\u lambda。示例中的两个lambda都可转换为此类型。