2013-01-11 78 views
2
for_each(ivec.begin(),ivec.end(), 
     [](int& a)->void{ a = a < 0 ? -a : a; 
    }); 

transform(ivec.begin(),ivec.end(),ivec.begin(), 
     [](int a){return a < 0 ? -a : a; 
    }); 

我目前正在學習lambda,我很好奇這兩個實現,我已經在上面發佈了,是不同的?for_each和變換

+3

第二個瞬間告訴你一些東西正在轉化,而不是循環。 – chris

+0

' - > void'是不必要的,並且注意在C++中函數的最後一個表達式語句的值沒有隱式的「返回」。 – Potatoswatter

+0

第二個有兩個相同的迭代器。你的編譯器很可能會注意到它,只使用一個,所以沒有性能差異。 –

回答

2

這第一個版本:

for_each(ivec.begin(),ivec.end(), 
     [](int& a)->void{ a = a < 0 ? -a : a; 
}); 

作品通過調用lambda函數

[](int& a)->void{ a = a < 0 ? -a : a; } 

一次範圍內的每一個元素,傳遞中的元素範圍作爲參數。因此,它通過直接更改其值來更新元素。

該第二版本:

transform(ivec.begin(),ivec.end(),ivec.begin(), 
    [](int a){return a < 0 ? -a : a; 
}); 

作品通過應用lambda函數

[](int a){return a < 0 ? -a : a;} 

每個在ivec.begin()ivec.end()範圍的元素,產生一系列值,和然後寫那些值返回到從ivec.begin()開始的範圍。這意味着它會覆蓋該範圍的原始內容,並將該函數應用到每個數組元素所產生的值的範圍內,從而覆蓋元素而不是就地修改。但是,淨效果與原始for_each相同。

希望這會有所幫助!

4

transform是什麼,在功能語言中,將被稱爲map。也就是說,它將函數應用於輸入範圍中的每個元素,並將輸出存儲到輸出範圍中。 (因此,它通常旨在不修改輸入,並且替代地存儲的範圍的輸出)

for_each簡單地丟棄從施加的函數的返回值(所以它可能修改輸入)。

這是主要的區別。它們是相似的,但是爲不同的目的而設計。

5

您顯示的兩個實現在邏輯上沒有不同(假設您通過添加返回來獲得第一個版本)。第一個修改元素,而最後一個用新值覆蓋元素。

我看到的最大差異是transform,你只能通過abs而不是重新實現它的lambda。

+0

+1對於額外的優點:當您想要更改元素時,'transform'用預先存在的函數可以更好地工作。 – chris

+1

abs'被重載,你將不得不'static_cast'它所需的超載的類型,這是一個相當痛苦。 – Potatoswatter

+0

@Potatoswatter:當你考慮ADL和UDT時,它會變得更加糟糕......如果只有我們有一個高級別的abs對象,可以對你發送的任何東西執行abs命令! –