[分享] std::forward, rvalue ref, and algorithm
有用過 <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
推
07/16 16:25, , 1F
07/16 16:25, 1F
→
07/16 17:13, , 2F
07/16 17:13, 2F
→
07/16 17:14, , 3F
07/16 17:14, 3F
→
07/16 18:27, , 4F
07/16 18:27, 4F
推
07/17 13:37, , 5F
07/17 13:37, 5F
推
07/17 13:52, , 6F
07/17 13:52, 6F
link 裡的 code 嗎? 就只是記錄哪些值被比較而已。
→
07/17 14:21, , 7F
07/17 14:21, 7F
已修正
推
07/17 14:39, , 8F
07/17 14:39, 8F
拿不到運算後 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)
→
07/17 15:11, , 9F
07/17 15:11, 9F
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章