簡體   English   中英

在未評估的語境中的lambdas(直到C ++ 20)

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

我目前正在閱讀P0315R1論文,該論文在未 評估的 背景下討論Lambda

文檔中有一個聲明解釋了為什么lambdas不能出現在未評估的上下文中(當然只有在C ++ 20之后) ,如下所示:

Lambdas是一種非常強大的語言功能,特別是在使用帶有自定義謂詞的高階算法或表示小的一次性代碼片段時。 然而,他們遭受了一個重要的限制,削弱了他們對創造性用例的有用性; 它們不會出現在無價值的背景下。 這個限制最初是為了防止lambda出現在簽名中,這會打開一堆蠕蟲進行重整,因為lambda需要有獨特的類型。

有人可以用一個例子解釋這個陳述嗎?

一點背景:鏈接器不理解函數重載 - 它們只能理解C語言中的函數名。 這就是C ++編譯器破壞你的函數名稱的原因。 void foo(int)變為_Z3fooi 受損的名稱會對所有參數的類型進行編碼。 如果您的函數是由模板實例化生成的,那么所有模板參數也會被編碼。 如果它們本身就是模板類,則它們的模板參數將被遞歸編碼,依此類推,直到達到像int或函數指針這樣的基本類型。

Lambdas使這個具有挑戰性,因為每個lambda都需要具有不同的類型。 這對函數中定義的lambdas來說並不算太糟糕:

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

foobar返回不同的類型。 如果你然后將它們傳遞給另一個函數模板,那么該模板的名稱會被偽裝成foo::__lambda1或其他類似的東西。

讓lambdas出現在decltype會破壞這種機制。

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

這是原型和定義嗎? 或者是這兩種不同的超載bar 如何在翻譯單元中識別它們(如何破壞名稱)?

到目前為止,C ++甚至禁止提出這個問題。 你鏈接的論文給出了答案:這樣的事情不能有聯系。 甚至不要試圖破壞它們。

如果我們在頭文件的函數簽名中有一個內聯函數,其中decltype為lambda 編譯器會在包含它的每個轉換單元中為此函數生成唯一的錯位名稱。

因此,最后鏈接器不能合並“相同”函數的這些多個定義,因為受損的名稱不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM