正Lambda:「[]{}」 - 深入探究意外
試圖研究lambda 表達式的神秘本質,「C 11 中不允許重新定義lambda,為什麼? Johannes Schaub 的一個奇特發現表明,在初始 lambda 之前添加一元運算子可以使其編譯。
查詢:
為什麼以下程式碼編譯時沒有錯誤:
int main() { auto test = +[]{}; // Note the unary operator + before the lambda test = []{}; }
這種行為是否符合 C標準?
揭曉:
是的,代碼符合 C 標準。此運算子顯著地觸發了 lambda 到普通函數指標的轉換。
展開:
編譯器解釋初始 lambda ([]{}) 並建立一個閉包物件。由於此 lambda 不捕獲任何變量,因此存在轉換函數,用於將閉包物件轉換為具有與閉包函數呼叫運算子相同的參數和返回類型的函數指標。
此轉換符合一元的要求操作員。的內建重載包括將任何類型 T 轉換為指向 T 的指標。閉包類型透過提供到函數指標的轉換來滿足此要求。
因此,表達式 auto test = []{ };推斷測試型別為 void(*)()。這使得第二行中的後續賦值成為可能,其中第二個 lambda/closure 物件也經歷了到函數指標的轉換,從而產生相容的賦值。
意義:
這種不尋常的行為凸顯了 lambda 表達式的多功能性和 C 語言的複雜機制。它可以透過將 lambda 表達式轉換為函數指標來重新分配它們,從而提供靈活性和程式碼最佳化的可能性。
以上是為什麼要新增一元「」運算子允許在 C 中重新分配 Lambda?的詳細內容。更多資訊請關注PHP中文網其他相關文章!