1

I would like to initialize a boost rolling window accumulator without having to do an assignment inside a function call.

This is what I see everyone do:

boost::accumulators::accumulator_set<double, boost::accumulators::stats<boost::accumulators::tag::rolling_mean>> acc(boost::accumulators::tag::rolling_window::window_size = 10);

How could I make the same accumulator without having the assignment inside the constructor call above?

1
  • Did you try creating a variable before, and use that? What happens when you do that?
    – cigien
    Commented Jun 25, 2020 at 18:52

1 Answer 1

1

It's not an assignment, it's a named-argument idiom. C++ doesn't have that, really, so this why it looks like an assignment: it's an Expression Template

You could of course figure out the type and use it, but that would not make any difference and just make it harder to use the library correctly:

boost::parameter::aux::tagged_argument_list_of_1<
    boost::parameter::aux::tagged_argument<
        boost::accumulators::tag::rolling_window_size_<0>, const int>>
    init(10);

ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>> acc(init);

I don't know about you, but I prefer the named-argument expression.


You can obviously write a helper function to remove the library details:

auto make_accum(int window) {
    return ba::accumulator_set<
        double,
        ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}

int main() {
    auto acc = make_accum(10);
}

This simply made the named argument into a positional argument using the knowledge about the statistics in in your set.

If you're worried about generic code, just pass the expression as the initializer in generic cases. That's how the library istelf is implemented:

template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
    return ba::accumulator_set<double, Stats> (init...);
}

Demo All 3 Approaches

Live On Coliru

#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics.hpp>
#include <boost/accumulators/statistics/rolling_mean.hpp>

namespace ba = boost::accumulators;

template <typename Stats, typename... Init> auto generic_accum(Init const&... init) {
    return ba::accumulator_set<double, Stats> (init...);
}

auto make_accum(int window) {
    return ba::accumulator_set<
        double,
        ba::stats<ba::tag::rolling_mean>> (ba::tag::rolling_window::window_size = window);
}

int main() {
    {
        boost::parameter::aux::tagged_argument_list_of_1<
            boost::parameter::aux::tagged_argument<
            boost::accumulators::tag::rolling_window_size_<0>, const int>>
            init(10);

        ba::accumulator_set<double, ba::stats<ba::tag::rolling_mean>>
            acc(init);
    }

    {
        auto acc = make_accum(10);
    }

    {
        auto acc = generic_accum<ba::stats<ba::tag::rolling_mean>>(ba::tag::rolling_window::window_size = 10);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.