编译器如何从delete-default-ctor lambda生成一个闭包?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编译器如何从delete-default-ctor lambda生成一个闭包?相关的知识,希望对你有一定的参考价值。

我想知道一个有删除-默认构造函数的lambda怎么能这样使用。

[](){}; // how is this translated by the compiler?

但这是行不通的

auto l = [](){std::cout << "lambda expr\n";}; // which ctor is invoked?

decltype (l) g; // doesn't work
  • 因为在C++ 20之前是不行的,但是C++ 20让lambda可以默认构造。

  • 如果没有构造函数可以调用,那么这个对象是怎么出现的呢?

答案

这有点像问:如果 int 没有构造函数,那么 int 当一个整数字词被评估时,对象从何而来?

编译器可以在不调用构造函数的情况下创建对象,只需在内存中生成设置对象所需的汇编或机器代码即可。它只是不让你在不调用构造函数的情况下创建各种类型的对象。(虽然,在C++20中,这种情况会有所改变,这要归功于 P0593.)

当编译器看到一个包含lambda表达式的表达式时,它只是继续生成在内存中设置闭包对象的代码。它没有义务将这些代码打包成函数,就像在构造函数中打包代码那样。甚至有可能编译器生成一些只有它知道如何调用的构造函数。从用户的角度来看,并不涉及构造函数。

另一答案

编译器不是在写C++,它不受我们同样的规则约束。

直到C++20 我们 不能用C++默认构造一个闭包类型。但这并不能改变一个事实,即标准说一个lambda表达式会产生一个闭包类型的对象。所以,编译器必须让它做这个事情,而它从来没有经过默认构造函数来做这个事情。这很好! 从来没有任何规则说它必须使用那种机械。

很抱歉没有更满意的答案,其实就是 "因为标准说的"。

另请参见:为什么编译器可以定义一个内置类型(如 int),而我们不能?因为!

以上是关于编译器如何从delete-default-ctor lambda生成一个闭包?的主要内容,如果未能解决你的问题,请参考以下文章

如何将编译器标志从 Autoconf 传递给 Automake?

如何将编译器标志从 clang 传递给 nvcc

如何从 Vala 编译器生成 GIR 文件?

如何从使用 /GL 编译的 .obj 文件中确定主要编译器版本?

如何在 VS 2017 中从其他编译器编译代码 [关闭]

如何编译使用从不同编译器编译的库的应用程序?