template <typename T>
T average(std::vector<T> distributionVector)
First of all, why is it limited to/specific to vector
?
Second, why are you passing it by value? Do you understand that this copies the entire vector?
Classically, such functions should take a pair of iterators to specify the input. As of C++20, you could use a to be continuedRange. By taking any parameter that satisfies the Range concept, that includes std::vector
and any other sequential collection as well.
If you change the template declaration to accept any container, that doesn't affect the code! Except... it would work for std::deque
, boost::small_vector
, etc. but would have trouble when you pass it a raw array, or certain types of range views. For this reason, use the non-member begin
, end
, size
, etc. to better abstract the collection/view.
Classically, this would be done with the "std::
two-step". With C++20, just use the newer std::ranges::begin
etc.
if (distributionVector.size() == 0)
Use empty
instead of comparing the size
with 0. And again, use the non-member.
When testing, include a plain C array as one of the tests; e.g.
constexpr int test_val_1[] = { 1,2,3,4,6,8,9,34,45,78,89 };
⋮
const auto result = variance<double>(test_val_1);
Notice that in this example I also specified that I want a floating-point calculation of the variance, even though the input is integers.
the API
In many calculators, the stats are computed incrementally. You submit each value (or value pair) as you compute them or enter them, often with a key labeled "Σ+". You can model this with a class that keeps intermediate accumulators but does not need the entire list of input at once. It can be used incrementally.
The class would use template arguments for the type to use for the accumulators, which IIRC are things like the count of items (n), the sum, the sum of the squares, and more for two-variable input.
The class would have functions to submit a value, or submit a range of values at once. These member functions can themselves be templates, to be flexible as to the parameter type.
It would have functions like average
and variance
that operate on the stored data. This way you can call for multiple stats without having to re-compute things or make multiple passes over the same data.