cpp*_*ast 3 c++ lambda c++11 c++20
我目前正在阅读P0315R1文章,该文章讨论了未评估背景下的Lambda。
该文档中有一条语句解释了为什么lambda不能在未评估的上下文中出现(当然,只有在C ++ 20之前),如下所示:
Lambda是一种非常强大的语言功能,尤其是在使用带有自定义谓词的高阶算法或表示小的可抛弃的代码段时。然而,它们遭受了一个重要的局限性,这限制了它们对创造性用例的实用性。它们不能出现在未经评估的环境中。此限制最初旨在防止lambda出现在签名中,因为lambda必须具有唯一的类型,否则该签名可能会打开一罐蠕虫进行处理。
有人可以举例说明这个说法吗?
一点背景知识:链接器不了解函数重载-它们仅像C语言一样理解函数名。这就是C ++编译器修改您的函数名称的原因。void foo(int)
成为_Z3fooi
。整齐的名称会编码所有参数的类型。如果您的函数是由模板实例化产生的,则所有模板参数也会被编码。如果它们本身是模板类,则将对它们的模板参数进行编码,以此类推,直到到达基本类型(如int或函数指针)为止。
Lambda带来了挑战,因为每个Lambda都必须具有不同的类型。对于在函数中定义的lambda来说,这还不错:
auto foo() { return [](){}; }
auto bar() { return [](){}; }
Run Code Online (Sandbox Code Playgroud)
foo
并bar
返回不同的类型。然后,如果将它们传递给另一个功能模板,则该模板的名称将被篡改,好像具有foo::__lambda1
某种作用。
让lambda出现decltype
会破坏这种机制。
void bar(decltype([](){}));
void bar(decltype([](){})) {}
Run Code Online (Sandbox Code Playgroud)
这是原型和定义吗?还是这两个不同的重载bar
?如何跨翻译单位识别它们(如何处理名称)?
直到现在,C ++甚至禁止问这个问题。您链接的论文给出了一个答案:诸如此类的事情不能相互关联。甚至不要试图破坏它们。
归档时间: |
|
查看次数: |
251 次 |
最近记录: |