簡體   English   中英

C ++ 0x lambdas編碼風格

[英]C++0x lambdas coding style

我想知道人們在編碼風格方面是如何使用C ++ 0x lambdas的。 最有趣的問題是編寫捕獲列表時有多徹底。 一方面,語言允許明確地列出捕獲的變量,並且通過“顯式優於隱式規則”,因此有必要進行詳盡的列表以清楚地說明意圖。 例如:

 int sum;
 std::for_each(xs.begin(), xs.end(), [&sum](int x) { sum += x });

對此的另一個論點是,由於ref-captured本地的生命周期不會因為它們被捕獲而改變(因此lambda很容易最終引用其生命周期已經結束的本地),因此使捕獲顯式有助於減少此類錯誤並追蹤他們。

另一方面,該語言還故意提供了自動捕獲所有引用的本地語言的快捷方式,因此很明顯它是打算使用的。 並且可以聲稱,對於上面的一個示例,即使使用自動捕獲也會非常清楚會發生什么,並且lambda的生命周期不會比周圍的范圍更長,所以沒有理由不使用它:

 int sum;
 std::for_each(xs.begin(), xs.end(), [&](int x) { sum += x });

顯然,這不一定是全有或全無,但必須有一些理由來決定何時自動捕獲,以及何時明確捕獲。 有什么想法嗎?

同樣的另一個問題是何時使用逐個拷貝 - [=] ,以及何時使用按引用捕獲 - [&] 逐個拷貝顯然更安全,因為沒有生命周期問題,因此有人可能會認為,只要不需要改變捕獲的值(或者看到從其他地方對其進行的更改),就應該默認使用它,並捕獲 - 在這種情況下,副引用應被視為(可能過早地)優化,僅在明顯有所作為的情況下應用。

另一方面,按引用捕獲幾乎總是更快(特別是因為它通常可以優化到副本,如果后者實際上更快,對於小類型和可內嵌模板函數,如大多數STL算法),並且如果lambda永遠不會超出其范圍(這也適用於所有STL算法),那么安全性是非常安全的,因此在這種情況下默認為引用捕獲是一種無關緊要且無害的優化。

你怎么看?

我從未聽說過“明確勝過隱性規則”規則,我不同意。 當然,有些情況確實如此,但也有很多情況並非如此。 這就是為什么0x畢竟用auto關鍵字添加類型推斷的原因。 (以及為什么在可能的情況下已經推斷出函數模板參數)有很多情況下隱含是優選的。

我還沒有真正使用過C ++ lambdas(除了探索VC10測試版),但我大部分時間都會使用后者

std::for_each(xs.begin(), xs.end(), [&](int x) { sum += x });

我的推理? 為什么不這樣做? 很方便。 有用。 而且它更容易維護。 當我修改lambda的主體時,我不必更新捕獲列表。 我為什么要明確一些編譯器比我更了解的東西? 編譯器可以根據實際使用的內容找出捕獲列表。

至於參考和價值的捕獲? 我會應用與常規功能相同的規則。 如果需要引用語義,請通過引用捕獲。 如果您需要復制語義,請執行此操作。 如果其中任何一個會這樣做,那么對於小型類型更喜歡值,如果復制是昂貴的則參考。

它與設計常規功能時的選擇似乎沒有什么不同。

我應該閱讀lambdas的規范,但這不是顯式捕獲列表的主要原因,以便您可以通過值捕獲一些變量而通過引用捕獲其他變量?

我最初的直覺是,按值獲取提供或多或少與Java的匿名內部類相同,這是已知數量。 但是,當您希望封閉范圍是可變的時,而不是使用size-size-1技巧,您可以通過引用來捕獲。 然后,您有責任將lambda的持續時間限制在referand的范圍內。

在實踐中,我同意你的意見,在處理算法時,通過引用捕獲應該是默認值,我希望它將是大多數用途。 Java中匿名內部類的常見用途是偵聽器。 在C ++中可以看到的偵聽器風格接口較少,因此需求較少,但仍然存在。 在這種情況下,最好嚴格按價值捕獲,以避免出錯的機會。 是否可以將shared_ptr的值捕獲成為一個很大的習慣用法?

但是,我還沒有使用過lambdas,所以我可能錯過了一些巨大的東西。

我可以在這里看到一個新的編碼標准規則! ;)

這有點做作,但為了突出顯示的“優勢”,請考慮以下內容:

void foo (std::vector<int> v, int x1)
{
  int sum = 0;
  std::for_each (v.begin ()
    , v.end ()
    , [&](int xl) { sum += x1; } 
}

現在,我故意為此選擇了可憐的名字等,但這只是為了說明這一點。 如果我們使用顯式捕獲列表,那么上面的代碼將無法編譯,但目前它將會編譯。

在非常嚴格的環境(安全關鍵)中,我可以看到這樣的規則是編碼標准的一部分。

我會選擇明確的捕獲列表,當你想要捕獲大量變量時(你可能做錯了)你可以使用抓取所有[&]捕獲列表。

我對這個問題的看法是明確的捕獲列表是理想的,應該避免使用隱式變體,只有這樣才能讓人們在實際需要時不必輸入大量的代碼。

我正在閱讀以下鏈接以更好地理解C ++ lambda。 示例中使用的編碼樣式非常簡潔,我可以遵循: http//uint32t.blogspot.com/2009/05/using-c0x-lambda-to-replace-boost-bind.html

暫無
暫無

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

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