13

次のオブジェクトがあるとします。

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

size内のすべてのオブジェクトの合計を取得するための最良の方法 (最も保守しやすく、読みやすいなど)はvector<Foo>何ですか? 解決策を投稿しますが、より良いアイデアに興味があります。

アップデート:

これまでのところ、次のことがわかっています。

  • std::accumulate とファンクター
  • std::accumulate とラムダ式
  • 普通の for ループ

他に実行可能な解決策はありますか? orを使用して保守可能なものを作成できますboost::bindstd::bind1st/2nd?

4

5 に答える 5

27

独自の提案に加えて、コンパイラがC ++ 0xラムダ式をサポートしている場合は、次の短いバージョンを使用できます。

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();});
于 2010-07-08T15:11:08.090 に答える
7

ブースト イテレータはエレガントですが、少し冗長になる可能性があります (範囲ベースのアルゴリズムがこれを改善します)。この場合、変換イテレータがその仕事を行うことができます:

#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);

注: パフォーマンスはほぼ同じです (私のコメントを参照): 内部的にtransformedtransorm_iterator.

于 2010-07-08T23:59:47.197 に答える
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());
于 2010-07-08T14:54:04.757 に答える
6

C++11 (およびそれ以降) の範囲ベースの for ループを使用する

std::vector<Foo> vFoo;
// populate vFoo with some values...
int totalSize = 0;
for (const auto& element: vFoo) {
    totalSize += element.size();
}
于 2016-07-31T23:23:00.343 に答える
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();
}
于 2010-07-08T15:16:14.753 に答える