My struct is a 2D coordinate:
template<typename T>
struct coordinate {
std::pair<T, T> coords;
coordinate() : coords({0, 0}) {}
const T x() const { return coords.first; }
const T y() const { return coords.second; }
// functions to set and manipulate x and y
};
I have a std::vector<coordinate<double>> vec
and would like to get averages of x and of y coordinates across the vector.
My way is (please don't judge)
double x_ = 0.;
double y_ = 0.;
for (auto v : vec) {
x_ += v.x();
y_ += v.y();
}
x_ /= vec.size();
y_ /= vec.size();
I assume there is a more suitable approach? I try to go for std::accumulate
, but don't know how to access the struct members in std::accumulate
.
I still struggle with C++ so some explanation to your approach would be great.
Like I said, if you want to do arithmetic operations on your type, you likely want to overload the operators. Thus you can do
#include <numeric>
#include <vector>
template<typename T>
struct coordinate {
std::pair<T, T> coords;
coordinate() : coords({0, 0}) {}
coordinate(T x,T y) : coords(x,y) {}
T x() const { return coords.first; }
T y() const { return coords.second; }
coordinate& operator+=(coordinate const& other){
coords.first += other.coords.first;
coords.second += other.coords.second;
return *this;
}
template<typename D>
coordinate& operator/=(D divider){
coords.first /= divider;
coords.second /= divider;
return *this;
}
};
template<typename T>
coordinate<T> operator+(coordinate<T> lhs, coordinate<T> const& rhs){
return lhs += rhs;
}
template<typename T, typename D>
coordinate<T> operator/(coordinate<T> lhs, D rhs){
return lhs /= rhs;
}
template<typename T>
coordinate<T> average(std::vector<coordinate<T>> const& vec){
if (vec.empty()){
return coordinate<T>{};
}
return std::accumulate(cbegin(vec), cend(vec), coordinate<T>{}) / vec.size();
}
int main()
{
std::vector<coordinate<double>> vec{{1,1},{2,0}};
auto avg = average(vec);
}