[英]Functor with std::for_each in C++
這是我從http://www.catonmat.net/blog/on-functors/復制的函子代碼。
#include <algorithm>
#include <iostream>
#include <list>
class EvenOddFunctor {
int even_;
int odd_;
public:
EvenOddFunctor() : even_(0), odd_(0) {}
void operator()(int x) {
if (x%2 == 0) even_ += x;
else odd_ += x;
}
int even_sum() const { return even_; }
int odd_sum() const { return odd_; }
};
int main() {
EvenOddFunctor evenodd;
int my_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// ??? why assign
evenodd = std::for_each(my_list,
my_list+sizeof(my_list)/sizeof(my_list[0]),
evenodd); // ???
std::cout << "Sum of evens: " << evenodd.even_sum() << "\n";
std::cout << "Sum of odds: " << evenodd.odd_sum() << std::endl;
// output:
// Sum of evens: 30
// Sum of odds: 25
}
為什么我們需要在操作之后像evenodd = std::for_each(my_list,
一樣)將值分配回evanodd
對象?我認為隨着從std :: for_each更新了evenodd對象,我不需要賦值操作,但沒有分配,結果顯示為0。
std::for_each
按值接受函子,這意味着它將修改本地副本。 作業會獲取該本地副本,因此您實際上可以看到修改后的版本。
這很重要,因為您的函子具有您感興趣的可變狀態,尤其是evenodd.even_sum
和evenodd.odd_sum
。
讓我們做一些實驗。
首先,嘗試不分配它,看看會發生什么。 嘗試之后,如果您發現了問題,則無需進一步閱讀,因此可以停止。
如果您無法解決問題,請進行第二個實驗,並如下更改main()
的相關部分:
const EvenOddFunctor evenodd_orig;
int my_list[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// ??? why assign
auto evenodd = std::for_each(my_list,
my_list+sizeof(my_list)/sizeof(my_list[0]),
evenodd_orig); // ???
這里的關鍵部分是您要將一個常量對象傳遞給std::for_each
。 這將編譯,但是如果std::for_each
以您認為的方式工作,則不應編譯。
畢竟, operator()
不是常量方法,因此,如果std::for_each
獲得const引用,它就不能調用可變的operator()
方法。
那是因為實際上發生的是std::for_each
對傳遞給它的函子進行內部復制。 它通過值而不是通過引用獲取函子參數,並且函子最終修改了其內部狀態。
這就是為什么std::for_each
返回函子對象的原因,這就是為什么您需要存儲它的原因,因為傳遞給std::for_each
的原始對象尚未修改!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.