In the previous chapter, we implemented several generic algorithms that operated on containers. Consider one of those algorithms again:
template<typename Container> void double_each_element(Container& arr) { for (int i=0; i < arr.size(); ++i) { arr.at(i) *= 2; } }
This algorithm is defined in terms of the lower-level operations .size() and .at(). This works reasonably well for a container type such as array_of_ints or std::vector, but it doesn't work nearly so well for, say, a linked list such as the previous chapter's list_of_ints:
class list_of_ints { struct node { int data; node *next; }; node *head_ = nullptr; node *tail_ = nullptr; int size_ = 0; public: int size() const { return size_; } int& at(int ...