问题
Having not found a 'boost' way of resetting an accumulator in C++, I came across a piece of code that seems to reset a boost accumulator. But don't understand how it is achieving it. The code is as below -
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
using namespace boost::accumulators;
template< typename DEFAULT_INITIALIZABLE >
inline void clear( DEFAULT_INITIALIZABLE& object )
{
object.DEFAULT_INITIALIZABLE::~DEFAULT_INITIALIZABLE() ;
::new ( boost::addressof(object) ) DEFAULT_INITIALIZABLE() ;
}
int main()
{
// Define an accumulator set for calculating the mean
accumulator_set<double, stats<tag::mean> > acc;
float tmp = 1.2;
// push in some data ...
acc(tmp);
acc(2.3);
acc(3.4);
acc(4.5);
// Display the results ...
std::cout << "Mean: " << mean(acc) << std::endl;
// clear the accumulator
clear(acc);
std::cout << "Mean: " << mean(acc) << std::endl;
// push new elements again
acc(1.2);
acc(2.3);
acc(3.4);
acc(4.5);
std::cout << "Mean: " << mean(acc) << std::endl;
return 0;
}
what do lines 7 to 12 do ? How does 'clear' manage to reset the accumulator ? Also, is there a standard boost way that I am missing and any other ways of achieving what the code above has done.
回答1:
To re-initialize an object just do:
acc = {};
What it does is {}
creates a default-initialized temporary object which gets assigned to acc
.
回答2:
what do lines 7 to 12 do?
They call the object's destructor, and then default-construct a new object (of the same type) in the same storage.
For sensible types, this will have the same effect as what Maxim's answer suggests, which is assigning a default-constructed temporary to the existing object.
A third alternative is to use a distinct object
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
using namespace boost::accumulators;
int main()
{
{
// Define an accumulator set for calculating the mean
accumulator_set<double, stats<tag::mean> > acc;
float tmp = 1.2;
// push in some data ...
acc(tmp);
acc(2.3);
acc(3.4);
acc(4.5);
// Display the results ...
std::cout << "Mean: " << mean(acc) << std::endl;
} // acc's lifetime ends here, afterward it doesn't exist
{
// Define another accumulator set for calculating the mean
accumulator_set<double, stats<tag::mean> > acc;
// Display an empty result
std::cout << "Mean: " << mean(acc) << std::endl;
// push elements again
acc(1.2);
acc(2.3);
acc(3.4);
acc(4.5);
std::cout << "Mean: " << mean(acc) << std::endl;
}
return 0;
}
来源:https://stackoverflow.com/questions/54572646/reset-boost-accumulator-c