Home3
Home3

Reputation: 131

Why do the accumulators from the C++ boost library have a function-like interface?

In the boost library, we use accumulators like this:

acc(1); // push things into acc
cout << max( acc ) << endl; // get its result

Why can't we define its interface like this:

acc.push(1);
cout << acc.max() << endl;

So why do the accumulators from the boost library have a function-like interface? What is the advantage of it?

Upvotes: 2

Views: 242

Answers (2)

Justin Meiners
Justin Meiners

Reputation: 11143

Here are two reasons:

  1. You can pass them to algorithms, such as for_each:

    acc = std::for_each(range.begin(), range.end(), acc);
    
  2. This gives all accumulators a uniform interface. This is helpful to combine them eg. with accumulator_set.

Upvotes: 1

phuclv
phuclv

Reputation: 41962

Here's my guess

The reason that operator () is used for pushing instead of push() is because acc(value) reads "accumulate another value" which sounds more natural than acc.push(value) which is "push a value to the accumulator"

Besides the accumulator can receive optional features like covariate or weight and that way probably the result looks and sounds better than acc.push(value, feature). Some examples from the documentation:

acc( 1.2, covariate1 =  12 );
acc( 2.3, covariate1 = -23 );
acc( 3.4, covariate1 =  34 );
acc( 4.5, covariate1 = -45 );

acc(1, weight = 2); //   1 * 2
acc(2, weight = 4); //   2 * 4
acc(3, weight = 6); // + 3 * 6

acc(1, weight = 2, covariate1 = 3);
acc(0, weight = 4, covariate1 = 4);
acc(2, weight = 9, covariate1 = 8);

And then max(acc) is used instead of acc.max() because it allows extensibility while still maintaining consistency. By writing a new function that receives an accumulator you'll be able to do other things to the accumulated list

std::cout << "Mean:   " << mean(acc) << std::endl;
std::cout << "Moment: " << accumulators::moment<2>(acc) << std::endl;

If a member method was used then there'll only be a limited number of default operations like acc.mean(), acc.max(), the remaining things must be used like a function such as product(acc), rolling_moment<2>(acc), kurtosis(acc), skewness(acc)... which breaks consistency

Upvotes: 0

Related Questions