簡體   English   中英

用C ++的std :: for_each函數

[英]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_sumevenodd.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.

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