使用std :: accumulate

Cha*_*l72 14 c++ stl

我总是尝试在任何地方使用STL算法,而不是编写手动循环.但是,我很难理解std::accumulate通常有用的方法.每当我需要计算总和或平均值时,我几乎总是求助于手动循环,因为我很难std::accumulate做到我需要的东西.

问题是我很少有一个简单的整数向量需要求和.通常,我想使用特定的成员变量对一个对象数组求和.是的,我知道有一个版本std::accumulate需要一个BinaryFunction,但我看到的问题是这个函数需要采用两个类型的值T,其中Tsum的类型,而不是操作数的类型.我无法理解这是如何有用的.

考虑一个我认为很常见的案例.我有以下课程:

struct Foo
{
    Foo(int cost_, int id_) : cost(cost_), id(id_)
    { }

    int cost;
    int id;
};
Run Code Online (Sandbox Code Playgroud)

现在,假设我想使用计算Foo对象数组的总和Foo::cost.

我想说:

std::vector<Foo> vec;
// fill vector with values
int total_cost = std::accumulate(vec.begin(), vec.end(), 0, sum_cost);
Run Code Online (Sandbox Code Playgroud)

sum_cost定义为:

int sum_cost(const Foo& f1, const Foo& f2)
{
    return f1.cost + f2.cost;
}
Run Code Online (Sandbox Code Playgroud)

问题是,这不起作用,因为std::accumulate需要一个BinaryFunction,它接收生成的sum类型的两个实例- 在这种情况下只是int.但这对我有什么用呢?如果我的BinaryFunction接受两个ints,我不能指定我想要求cost字段的总和.

那么,为什么这样std::accumulate设计呢?我在这里看不到明显的东西吗?

Edw*_*nge 19

你对累积运算符采用两种相同类型的错误.只有你愿意,它才会这样做.具体使用运营商sum = op(sum, *iter).因此你的代码:

int count = std::accumulate(stuff.begin(), stuff.end(), 0, [](int current_sum, stuff_value_t const& value) { return current_sum + value.member; });
Run Code Online (Sandbox Code Playgroud)

如果你不能使用lambda,那么当然你使用标准的绑定器或boost :: bind.

  • @Channel - 是的.那个来源是错误的. (3认同)