2016-10-09 16 views
23

我用lambda表達式和編譯器,因爲another question這裏SO實驗。
我剛剛意識到(這是完全正常的確實)下面的代碼是有效的:是[] <typename>(){}一個有效的lambda定義?

int main() { 
    auto l = [](){}; 
    l.operator()(); 
} 

事實上的標準說,閉合類型有一個公共內聯函數調用操作等,從而能夠調用它是有道理的。

我不能看着的標準解釋(當然,工作草案)的事實是,GCC(6.1)編譯下面的代碼片段(鐺3.9沒有):

int main() { 
    auto l = []<typename>(){}; 
    l.operator()<void>(); 
} 

沒有警告,沒有錯誤。它是有效的代碼還是應該被編譯器拒絕?

+0

[編譯成功(http://cpp.sh/4asuj) – amanuel2

+1

@ amanuel2我知道,它編譯(海灣合作委員會至少),但問題是,如果它是否有效。 – skypjack

+1

C++ 14將允許「模板」 lambda表達式,但是這與'auto'關鍵字來代替'<>'模板語法(見https://stackoverflow.com/questions/3575901/can-lambda-functions-be -templated)。也許GCC開發者想要嘗試不同的方式來添加這種功能? –

回答

21

在N4140 5.1.2 [expr.prim.lambda],一個Lambda表達式定義爲

λ-導引λ-說明符選擇化合物語句

其中「lambda-introducer」[],包含可選的「lambda-capture」「lambda聲明器 opt是開始的東西‘(參數聲明子句)’

[]<typename>(){} 

因爲拉姆達引導和拉姆達聲明符之間的東西不符合這一要求,所以它不是一個有效的lambda表達式。

因此,您的示例代碼無效C++,並應被編譯器拒絕。


因爲這也是標記,我通過GNU C++ extensions列表中點擊。我沒有找到任何可以使GNU C++中的語法合法的擴展。但是,根據this proposal(P0428R0)的第4部分,它建議將模板化lambda表添加到C++中,gcc在2009年獲得了上述論文的實驗實現。這可能解釋了爲什麼gcc不會在此抱怨。

+4

鑑於這個問題被標記爲GCC,值得檢查在這方面是否有標準的gnu擴展。 – Vality

+1

@Vality同意,補充說。謝謝。 –

+0

我向GCC開了一個問題,它是否值得一提呢? – skypjack

2

這似乎是一個GCC擴展(模板la​​mbda表達式)。

#include <iostream> 

int main() { 
    auto l = []<typename T>(T const& x){ std::cout << __PRETTY_FUNCTION__ << " " << x << std::endl;}; 
    l(42); 
    l("Hello world"); 
} 

結果

main()::<lambda(const T&)> [with T = int] 42 
main()::<lambda(const T&)> [with T = char [12]] Hello world 
+0

你能提供一個鏈接到這個文檔嗎?我一直無法找到它,這就是爲什麼我排除了作爲擴展的可能性。謝謝。 – skypjack

+0

http://gcc.gnu.org/ml/gcc/2009-08/msg00174.html是最接近的我可以找到@skypjack – etarion

相關問題