编译器如何从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?