2010-03-19 38 views
7

Gần đây tôi đã bắt đầu tự mình dạy thư viện mẫu tiêu chuẩn. Tôi đã tò mò là tại sao phương thức GetTotal() trong lớp này trở về 0?functor return 0

... 

class Count 
{ 
public: 
    Count() : total(0){} 
    void operator() (int val){ total += val;} 
    int GetTotal() { return total;} 
private: 
    int total; 
}; 

void main() 
{ 
    set<int> s; 
    Count c; 
    for(int i = 0; i < 10; i++) s.insert(i); 
    for_each(s.begin(), s.end(), c); 
    cout << c.GetTotal() << endl; 
} 

Trả lời

13

for_each lấy hàm theo giá trị. Nghĩa là, nó sử dụng một bản sao của functor và không phải là functor. Địa chỉ c địa phương của bạn không thay đổi.

for_each trả về functor nó được sử dụng, tuy nhiên, do đó bạn có thể làm:

Count c; 
c = for_each(s.begin(), s.end(), c); 

Hoặc idiomatically hơn:

Count c = for_each(s.begin(), s.end(), Count()); 

Tuy nhiên, tồn tại chức năng như vậy rồi (không cần functor của bạn) :

int total = std::accumulate(s.begin(), s.end(), 0); 
+1

Đó là bộ đếm trực quan. Bạn có biết tại sao họ làm theo cách đó? –

+0

Đó là bởi vì c là trên ngăn xếp và được truyền theo giá trị cho for_each, do đó, một bản sao của c được thông qua. Nó không có gì để làm với for_each (khác sau đó phải mất một functor thay vì một con trỏ đến một functor), nhưng thay vì với ngữ nghĩa của ngôn ngữ. Vì sao phải mất một hàm và không phải là một con trỏ đến một hàm con có thể liên quan đến nó cũng có thể lấy một con trỏ tới một hàm, do đó không có vấn đề gì được truyền vào, for_each có thể gọi f(). Nhưng phần đó chỉ là phỏng đoán –

+0

@Mark: Tôi không biết thực sự. Họ có thể làm cho nó trở thành một tham chiếu và không có vấn đề gì. Tôi không thể nghĩ về một tình huống mà nó là một tài liệu tham khảo sẽ làm tôi ngạc nhiên. Tôi cũng tò mò. @ Brandon: Anh ấy không hỏi câu trả lời của tôi có nghĩa là gì. Ông có nghĩa là "tại sao họ không thiết kế nó để lấy hàm theo tham chiếu thay vì bằng giá trị?" :) – GManNickG