[英]Passing lambda as a template parameter? ( c++20, lambdas in unevaluated context)
[英]lambdas in unevaluated contexts (Until C++20)
一點背景:鏈接器不理解函數重載 - 它們只能理解C語言中的函數名。 這就是C ++編譯器破壞你的函數名稱的原因。 void foo(int)
變為_Z3fooi
。 受損的名稱會對所有參數的類型進行編碼。 如果您的函數是由模板實例化生成的,那么所有模板參數也會被編碼。 如果它們本身就是模板類,則它們的模板參數將被遞歸編碼,依此類推,直到達到像int或函數指針這樣的基本類型。
Lambdas使這個具有挑戰性,因為每個lambda都需要具有不同的類型。 這對函數中定義的lambdas來說並不算太糟糕:
auto foo() { return [](){}; }
auto bar() { return [](){}; }
foo
和bar
返回不同的類型。 如果你然后將它們傳遞給另一個函數模板,那么該模板的名稱會被偽裝成foo::__lambda1
或其他類似的東西。
讓lambdas出現在decltype
會破壞這種機制。
void bar(decltype([](){}));
void bar(decltype([](){})) {}
這是原型和定義嗎? 或者是這兩種不同的超載bar
? 如何在翻譯單元中識別它們(如何破壞名稱)?
到目前為止,C ++甚至禁止提出這個問題。 你鏈接的論文給出了答案:這樣的事情不能有聯系。 甚至不要試圖破壞它們。
如果我們在頭文件的函數簽名中有一個內聯函數,其中decltype為lambda 。 編譯器會在包含它的每個轉換單元中為此函數生成唯一的錯位名稱。
因此,最后鏈接器不能合並“相同”函數的這些多個定義,因為受損的名稱不同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.