简体   繁体   English

在未评估的语境中的lambdas(直到C ++ 20)

[英]lambdas in unevaluated contexts (Until C++20)

I am currently reading P0315R1 paper which talks about Lambdas in unevaluated contexts 我目前正在阅读P0315R1论文,该论文在未 评估的 背景下讨论Lambda

There is a statement in the document which explains why lambdas can't appear in unevaluated contexts (of course only until C++20) as below: 文档中有一个声明解释了为什么lambdas不能出现在未评估的上下文中(当然只有在C ++ 20之后) ,如下所示:

Lambdas are a very powerful language feature, especially when it comes to using higher-order algorithms with custom predicates or expressing small, disposable pieces of code. Lambdas是一种非常强大的语言功能,特别是在使用带有自定义谓词的高阶算法或表示小的一次性代码片段时。 Yet, they suffer from one important limitation which cripples their usefulness for creative use cases; 然而,他们遭受了一个重要的限制,削弱了他们对创造性用例的有用性; they can't appear in unevaluated contexts. 它们不会出现在无价值的背景下。 This restriction was originally designed to prevent lambdas from appearing in signatures, which would have opened a can of worm for mangling because lambdas are required to have unique types. 这个限制最初是为了防止lambda出现在签名中,这会打开一堆蠕虫进行重整,因为lambda需要有独特的类型。

Can somebody please explain this statement with an example? 有人可以用一个例子解释这个陈述吗?

A little background: Linkers don't understand function overloading - they only understand function names like in the C language. 一点背景:链接器不理解函数重载 - 它们只能理解C语言中的函数名。 That's why C++ compilers mangle your function names. 这就是C ++编译器破坏你的函数名称的原因。 void foo(int) becomes _Z3fooi . void foo(int)变为_Z3fooi The mangled name encodes the types of all the arguments. 受损的名称会对所有参数的类型进行编码。 If your function resulted from a template instantiation, all template arguments get encoded too. 如果您的函数是由模板实例化生成的,那么所有模板参数也会被编码。 If they are themselves template classes, their template arguments get encoded, and so on recursively until the primitive types like ints or function pointers are reached. 如果它们本身就是模板类,则它们的模板参数将被递归编码,依此类推,直到达到像int或函数指针这样的基本类型。

Lambdas make this challenging because each lambda is required to have distinct type. Lambdas使这个具有挑战性,因为每个lambda都需要具有不同的类型。 This isn't too bad for lambdas defined in functions: 这对函数中定义的lambdas来说并不算太糟糕:

auto foo() { return [](){}; }
auto bar() { return [](){}; }

foo and bar return different types. foobar返回不同的类型。 If you then pass them to another function template, that template's name is mangled as if with foo::__lambda1 or something to that effect. 如果你然后将它们传递给另一个函数模板,那么该模板的名称会被伪装成foo::__lambda1或其他类似的东西。

Letting lambdas appear in decltype would break this mechanism. 让lambdas出现在decltype会破坏这种机制。

void bar(decltype([](){}));
void bar(decltype([](){})) {}

Is this a prototype and a definition? 这是原型和定义吗? Or are these two different overloads of bar ? 或者是这两种不同的超载bar How to identify them across translation units (how to mangle the names)? 如何在翻译单元中识别它们(如何破坏名称)?

Until now, C++ forbid even asking this question. 到目前为止,C ++甚至禁止提出这个问题。 The paper you linked gives an answer: things like this can't have linkage. 你链接的论文给出了答案:这样的事情不能有联系。 Don't even try to mangle them. 甚至不要试图破坏它们。

If we have a inline function with decltype of lambda in the function signature in the header file. 如果我们在头文件的函数签名中有一个内联函数,其中decltype为lambda The compiler generates a unique mangled name for this function in every translation unit in which it was included. 编译器会在包含它的每个转换单元中为此函数生成唯一的错位名称。

So at the end the linker can't merge these multiple definitions of the "same" function because the mangled names differ. 因此,最后链接器不能合并“相同”函数的这些多个定义,因为受损的名称不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM