簡體   English   中英

是[] <typename> (){}一個有效的lambda定義?

[英]Is []<typename>(){} a valid lambda definition?

我正在嘗試使用lambdas和編譯器,因為這里有另外一個問題
我剛剛意識到(並且確實非常正常)以下代碼是有效的:

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

實際上標准說閉包類型有一個公共內聯函數調用操作符等等,因此能夠調用它是有意義的。

通過查看標准(以及工作草案)我無法解釋的是,GCC(6.1)編譯了以下代碼段(clang 3.9沒有):

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

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

在N4140 5.1.2 [expr.prim.lambda]中,Lambda表達式定義為

lambda-introducer lambda-declarator opt復合語句

其中“lambda-introducer”[] ,包含可選的“lambda-capture”“lambda-declarator opt是以“(parameter-declaration-clause)”開頭的東西。

[]<typename>(){}

不符合該要求,因為lambda介紹者和lambda聲明符之間存在某種東西,因此它不是有效的lambda表達式。

因此,您的示例代碼不是有效的C ++,應該被編譯器拒絕。


由於這也標記為 ,我點擊了GNU C ++擴展列表。 我沒有找到任何可以使GNU C ++中的語法合法的擴展。

然而,根據該提案的第4節(P0428R0),該提議將模板化的lambda添加到C ++中,gcc在2009年得到了上述論文的實驗性實現。這可能解釋了為什么gcc不會在這里抱怨。

它似乎是一個GCC擴展(模板化的lambdas)。

#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

給定的代碼格式良好,並且從C ++ 20開始按預期工作。

Per [expr.prim.lambda]

lambda表達式
lambda-introducer lambda-declarator opt復合語句
lambda-introducer < template-parameter-list > requires-clause opt lambda-declarator opt compound-statement

最后一行反映了這種語法。 Per [expr.prim.lambda] / 5

一個lambda是一個通用拉姆達 ,如果有一個DECL-說明符是一個占位符型說明符λ-表達參數聲明DECL說明符-SEQ, 或者如果拉姆達具有模板參數列表

暫無
暫無

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

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