2011-08-04 30 views
4

對於像std :: map這樣的地圖,我該如何累計它的值'sum?
其實,我用函子和std :: for_each算法做了它。但我也想使用std :: accumulate算法。
我不知道如何將它應用於std :: map。
這甚至可能嗎?如何將std :: accumulate算法應用於關聯容器?

struct Accumurator 
    : std::unary_function<std::pair<int, int>, void> 
{ 
    Accumurator() 
     : totalValue_(0) 
    { 
    } 

    void operator()(const std::pair<int, int>& p) 
    { 
     totalValue_ += p.second; 
    } 

    int result() const 
    { 
     return totalValue_; 
    } 

    int totalValue_; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::map<int, int> m; 
    m.insert(make_pair(1, 10)); 
    m.insert(make_pair(2, 10)); 
    m.insert(make_pair(3, 10)); 
    m.insert(make_pair(4, 10)); 
    m.insert(make_pair(5, 10)); 
    m.insert(make_pair(6, 10)); 

    int totalSum = std::for_each(m.begin(), m.end(), Accumurator()).result(); 

    // How can I apply accumulate algorithm for associative containers. 
    // int totalSum = accumulate(m.begin(), m.end(), ???); 

    return 0; 
} 

回答

6

差不多。函子必須是二元運營商正在返回值的類型爲第一和範圍類型作爲第二個參數:

x = Functor(init, *it++); 
x = Functor(x, *it++); 
x = Functor(x, *it++); 
// ... until it == end 

所以你並不需要一個有狀態的函子都,一個簡單的函數會做:

int map_acc(int lhs, const std::pair<int, int> & rhs) 
{ 
    return lhs + rhs.second; 
} 

const int sum = std::accumulate(m.begin(), m.end(), 0, map_acc); 
+1

Aha,** _ Fn2 ** type表示二元函數/函子?很有幫助。我沒有注意到這一點。 – Benjamin

2

std::accumulate需要一個初始化參數,並執行二進制運算。 您的二進制操作需要接受一對作爲第二個參數,int作爲第一個參數並返回int。

struct pair_add { 
    int operator()(int i, const std::pair<int, int>& x) { 
    return i + x.second; 
    } 
}; 
//use as 
int totalSum = accumulate(m.begin(), m.end(), 0, pair_add()); 

真正的問題是讓仿函數儘可能通用。