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

Mic*_*fik 11 c++ containers stl member-functions

假设我有以下对象:

struct Foo
{
    int size() { return 2; }
};
Run Code Online (Sandbox Code Playgroud)

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

更新:

到目前为止,我们有:

  • std :: accumulate和一个仿函数
  • std :: accumulate和一个lambda表达式
  • 普通的'for-loop

还有其他可行的解决方案吗?你可以使用boost::bind或制作可维护的东西std::bind1st/2nd吗?

jal*_*alf 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();});
Run Code Online (Sandbox Code Playgroud)


Mic*_*fik 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());
Run Code Online (Sandbox Code Playgroud)


raf*_*fak 7

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

#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);
Run Code Online (Sandbox Code Playgroud)

编辑:用" 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);
Run Code Online (Sandbox Code Playgroud)

注意:表现大致相同(见我的评论):内部,transformed使用transorm_iterator.


Mic*_*ler 6

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

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