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?
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...);
}
#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);
}
}