gpt4 book ai didi

c++ - 为什么 [=]{} 有 lambda 捕获?

转载 作者:IT老高 更新时间:2023-10-28 13:01:29 26 4
gpt4 key购买 nike

在直观的层面上,不需要携带任何状态(通过引用或其他方式)的 lambda 应该可以干净地转换为裸函数指针是有道理的。但是,我最近惊讶地发现 GCC、Clang 和 MSVC 中出现以下错误:

int main(int, char *[]) {
void (*fp)() = []{}; // OK
//fp = [=]{}; // XXX - no user defined conversion operator available
//fp = [&]{}; // XXX - same ...
}

C++17 规范(或至少 visible public draft version N4713)在 § 8.4.5.1 [expr.prim.lambda.closure] 的第 7 项中提到了带有和不带有捕获的 lambda:

The closure type for a non-generic lambda-expression with no lambda-capture whose constraints (if any) are satisfied has a conversion function to pointer to function with C++ language linkage (10.5) having the same parameter and return types as the closure type’s function call operator. ...

但是,查看正式语法,您可以在第 8.4.5 节中看到以下内容[expr.prim.lambda]:

  • lambda-expression :
    • lambda-introducer compound-statement
    • ...
  • lambda-introducer :
    • [ lambda-captureopt ]
  • ...

并在 § 8.4.5.2 [expr.prim.lambda.capture]:

  • lambda-capture :
    • capture-default
    • capture-list
    • capture-default, capture-list
  • capture-default :
    • &
    • =

因此,令我沮丧的是,所有编译器实际上都在遵守法律条文......

为什么语言将捕获的存在定义为声明中的一种狭义语法区别,而不是基于主体是否包含对任何非静态/捕获状态的引用?

最佳答案

允许转换的更改是由国家机构评论发起的。见 n3052: Converting Lambdas to Function Pointers指国家机构comment UK 42 :

A lambda with an empty capture list has identical semantics to a regular function type. By requiring this mapping we get an efficient lambda type with a known API that is also compatible with existing operating system and C library functions.

N3052 的分辨率为:

Resolution: Add a new paragraph: "A lambda expression with an empty capture set shall be convertible to pointer to function type R(P), where R is the return type and P is the parameter-type-list of the lambda expression." Additionally it might be good to (a) allow conversion to function reference and (b) allow extern "C" function pointer types.

...

Add a new paragraph after paragraph 5. The intent of this edit is to obtain a closure-to-function-pointer conversion for a lambda with no lambda-capture.

The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type's function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type's function call operator.

这就是我们今天所处的位置。请注意评论说 empty capture list,我们今天所拥有的似乎与评论中措辞的意图相符。

看起来这是基于国家机构评论的修复,并且应用范围很窄。

关于c++ - 为什么 [=]{} 有 lambda 捕获?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53530697/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com