看板 C_and_CPP 關於我們 聯絡資訊
有用過 <algorithm> 的人或許會發現,傳給該演算法的 compare functor 或是 predicator 都是 pass-by-value,這對於想要在 functor 裡面偷動手腳存東西的 人來說是個問題,舉個例子: template<typename T> struct my_compare{...}; void func() { my_compare<int> cmp; std::vecotr<int> v{3,2,1,6,9}; // 偷用一下 C++11 std::sort(v.begin(), v.end(), cmp); } 注意 std::sort 是遞迴地執行運算, 因此 cmp 這個 functor 會被不斷地複製 以 sort n 個數值來講,平均複製的次數是 O(nlogn),另外由於 sort 設計的關係 他不會回傳 functor ,以致於沒辦法在 cmp 內部保留狀態。 在 C++11 以前的解法一個是自己改寫 sort ,確保 functor 是 pass by reference (明確指定樣板參數型別),另一個就是用 boost::bind 去把 functor 重新打包 std::sort(v.begin(), v.end(), boost::bind( &my_compare<int>::operator(), &cmp, _1, _2) ); 這樣複製就是發生在打包出來的 unspecified function 而不是 cmp 本身; 註:感謝 Chikei 提醒,TR1 裡面就有 reference_wrapper。可以簡單的 sort(..., ..., ref(cmp); 達成本文目的。 雖然目的已經達成,可是我還沒用到 std::foward<T> =.= ... 所以用了他有甚麼效果,主要就是 rvalue reference 的解析。 在 C++11 之後,利用 std::forward 可以保證飾詞(const) 與 reference 語意不會丟失,因此,他能正確解析出 rvalue reference 並呼叫 move constructor,(這個時候當然狀態就拿不回來啦): http://yangacer.twbbs.org/~yangacer/samples/forward.html 只是 GCC4.7 裡的 <algorithm> 沒有改成如此。另外,在 functor 裡面保 存狀態到底是不是個好主意,我也不太確定。 ------ 寫完才想到 Lambda function ...。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.123.17.77
damody:推好仔細 "gcc4.7沒改" 不過我還在 mingw 4.6.2 07/16 16:25
legnaleurc:compare 用的 function 有 state 的確不是個好主意 07/16 17:13
legnaleurc:因為呼叫次序次數都不確定 07/16 17:14
adxis:可能 unary functor 比較常用吧 e.g. for_each 07/16 18:27
zaqimon:我真的不懂C++啊 我還是用C就好了 07/17 13:37
shaopin:你這code是打算怎麼用儲存好的狀態? 假設可以的話... 07/17 13:52
link 裡的 code 嗎? 就只是記錄哪些值被比較而已。
Chikei:pre-C++11有tr1::reference_wrapper可以用 07/17 14:21
已修正
shaopin:除了sort以外 其他的algorithm還有也是這樣的嗎? 07/17 14:39
拿不到運算後 functor 的嗎? 沒有 return functor 的。 ※ 編輯: adxis 來自: 220.132.19.9 (07/17 14:53) ※ 編輯: adxis 來自: 220.132.19.9 (07/17 14:55) ※ 編輯: adxis 來自: 220.132.19.9 (07/17 15:04)
loveme00835:http://ideone.com/Q63iO 07/17 15:11