Step 1 of 5
Making a class iterable
You've used range-for on vectors, strings, maps and arrays. Your own classes can join in, and it's easier than it looks, because range-for is just shorthand. The compiler rewrites it into iterator calls:
for (auto& x : c) { ... }
// becomes roughly:
for (auto it = c.begin(), end = c.end(); it != end; ++it) { auto& x = *it; ... }
So any type with begin() and end() members works with range-for, and with every standard algorithm. If your class stores its data in a plain array, pointers are perfectly good iterators: they already support *, ++ and !=.
#include <algorithm>
#include <iostream>
class Week {
public:
void set(int day, double hours) { hours_[day] = hours; }
double* begin() { return hours_; }
double* end() { return hours_ + 7; } // one past the last day
const double* begin() const { return hours_; }
const double* end() const { return hours_ + 7; }
private:
double hours_[7] = {};
};
double total(const Week& w) {
double t = 0;
for (double h : w) t += h; // uses the const versions
return t;
}
int main() {
Week w;
w.set(0, 8);
w.set(2, 6.5);
for (double& h : w) h += 0.5; // non-const: modify in place
std::cout << total(w) << "\n";
std::cout << *std::max_element(w.begin(), w.end()) << "\n";
}
18
8.5
Why two versions?
totalreceives aconst Week&. On a const object, onlyconstmember functions can be called, so it needsbegin() constandend() const. Those returnconst double*, so the loop can read but not change.- The loop in
mainmodifies the hours throughdouble&, which needs the non-const versions returningdouble*.
Providing both is the standard pattern for every container.
Your task: only the filled part
Scoreboard has room for 8 scores but only count_ are real. So end() is scores_ + count_, not scores_ + 8. Then range-for and algorithms automatically see only the scores that were added.
Your turn: give Scoreboard begin() and end() (both a non-const and a const version) that return pointers into its fixed array, covering only the count_ scores that were added.