对容器中所有元素的成员函数的结果求和的最佳方法是什么?

时间:2010-07-08 14:53:47

标签: c++ stl containers member-functions

假设我有以下对象:

struct Foo
{
    int size() { return 2; }
};

获得size中所有对象的总vector<Foo>的最佳方法(最易维护,可读等)是什么?我会发布我的解决方案,但我对更好的想法感兴趣。

更新

到目前为止,我们已经:

  • std :: accumulate和一个仿函数
  • std :: accumulate和lambda表达式
  • plain ol'for-loop

还有其他可行的解决方案吗?您可以使用boost::bindstd::bind1st/2nd来维护某些内容吗?

5 个答案:

答案 0 :(得分:25)

除了你自己的建议,如果你的编译器支持C ++ 0x lambda表达式,你可以使用这个更短的版本:

std::vector<Foo> vf;

// do something to populate vf


int totalSize = std::accumulate(vf.begin(),
                                vf.end(),
                                0, 
                                [](int sum, const Foo& elem){ return sum + elem.size();});

答案 1 :(得分:7)

使用std::accumulate和仿函数。

#include <functional>
#include <numeric>

struct SumSizes : public std::binary_function<int, Foo, int>
{
    int operator()(int total, const Foo& elem) const
    {
        return total + elem.size();
    }
};

std::vector<Foo> vf;

// do something to populate vf

int totalSize = std::accumulate(vf.begin(),
                                vf.end(),
                                0, 
                                SumSizes());

答案 2 :(得分:7)

我找到了Boost迭代器elegants,虽然它们可能有点冗长(基于范围的算法会使这更好)。在这种情况下,transform iterators可以完成这项工作:

#include <boost/iterator/transform_iterator.hpp>
//...

int totalSize = std::accumulate(
    boost::make_transform_iterator(vf.begin(), std::mem_fn(&Foo::size)),
    boost::make_transform_iterator(vf.end(), std::mem_fn(&Foo::size)),0);

修改:将“boost::bind(&Foo::size,_1)”替换为“std::mem_fn(&Foo::size)

编辑:我刚刚发现Boost.Range库已经更新,引入了范围算法!这是同一解决方案的新版本:

#include <boost/range/distance.hpp> // numeric.hpp needs it (a bug?)
#include <boost/range/numeric.hpp> // accumulate
#include <boost/range/adaptor/transformed.hpp> // transformed
//...
int totalSize = boost::accumulate(
    vf | boost::adaptors::transformed(std::mem_fn(Foo::size)), 0);

注意:表演大致相同(请参阅我的评论):在内部,transformed使用transorm_iterator

答案 3 :(得分:6)

使用C ++ 11(及更高版本)基于范围的for循环

std::vector<Foo> vFoo;
// populate vFoo with some values...
int totalSize = 0;
for (const auto& element: vFoo) {
    totalSize += element.size();
}

答案 4 :(得分:4)

这是脚踏实地的解决方案:

typedef std::vector<Foo> FooVector;
FooVector vf;
int totalSize = 0;
for (FooVector::const_iterator it = vf.begin(); it != vf.end(); ++it) {
  totalSize += it->size();
}