std::vector v{1, 2, 3, 4, 5};
++(*v.begin()); // vector<int>'s non-const iterator
*v.begin(); // vector<int>'s const iterator
v.cbegin(); // vector<int>'s const iterator
std::vector v{1, 2, 3, 4, 5};
// Copy all 2s
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it == 2) {
v.push_back(2);
}
}
// Erase all 2s
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it == 2) {
v.erase(it);
}
}
std::vector v{1, 2, 3, 4, 5};
// Copy all 2s
for (auto it = v.begin(); it != v.end(); ++it) {
if (*it == 2) {
v.push_back(2);
}
}
std::vector v{1, 2, 3, 4, 5};
// Erase all even numbers (C++11 and later)
for (auto it = v.begin(); it != v.end(); ) {
if (*it % 2 == 0) {
it = v.erase(it);
} else {
++it;
}
}
A custom iterator class should look, at minimum, like this
class Iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using reference = T&;
using pointer = T*; // Not strictly required, but nice to have.
using difference_type = int;
reference operator*() const;
Iterator& operator++();
Iterator operator++(int) {
auto copy{*this};
++(*this);
return copy;
}
// This one isn't strictly required, but it's nice to have.
pointer operator->() const { return &(operator*()); }
friend bool operator==(const Iterator& lhs, const Iterator& rhs) { ... };
friend bool operator!=(const Iterator& lhs, const Iterator& rhs) { return !(lhs == rhs); }
};
class Container {
// Make the iterator using one of these by convention.
class iterator {...};
using iterator = ...;
// Need to define these.
iterator begin();
iterator end();
// If you want const iterators (hint: you do), define these.
const_iterator begin() const { return cbegin(); }
const_iterator cbegin() const;
const_iterator end() const { return cend(); }
const_iterator cend() const;
};
class Container {
// Make the iterator
class reverse_iterator {...};
// or
using reverse_iterator = ...;
// Need to define these.
reverse_iterator rbegin();
reverse_iterator rend();
// If you want const reverse iterators (hint: you do), define these.
const_reverse_iterator rbegin() const { return crbegin(); }
const_reverse_iterator crbegin();
const_reverse_iterator rend() const { return crend(); }
const_reverse_iterator crend() const;
};
class Container {
// Make the iterator using these.
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
// Need to define these.
reverse_iterator rbegin() { return reverse_iterator{end()}; }
reverse_iterator rend() { return reverse_iterator{begin()}; }
// If you want const reverse iterators (hint: you do), define these.
const_reverse_iterator rbegin() const { return crbegin(); }
const_reverse_iterator rend() const { return crend(); }
const_reverse_iterator crbegin() const { return const_reverse_iterator{cend()}; }
const_reverse_iterator crend() const { return const_reverse_iterator{cbegin()}; }
};
Text
class Iterator {
...
using reference = T&;
using difference_type = int;
Iterator& operator+=(difference_type rhs) { ... }
Iterator& operator-=(difference_type rhs) { return *this += (-rhs); }
reference operator[](difference_type index) { return *(*this + index); }
friend Iterator operator+(const Iterator& lhs, difference_type rhs) {
Iterator copy{*this};
return copy += rhs;
}
friend Iterator operator+(difference_type lhs, const Iterator& rhs) { return rhs + lhs; }
friend Iterator operator-(const Iterator& lhs, difference_type rhs) { return lhs + (-rhs); }
friend difference_type operator-(const Iterator& lhs, const Iterator& rhs) { ... }
friend bool operator<(Iterator lhs, Iterator rhs) { return rhs - lhs > 0; }
friend bool operator>(Iterator lhs, Iterator rhs) { return rhs - lhs < 0; }
friend bool operator<=(Iterator lhs, Iterator rhs) { !(lhs > rhs); }
friend bool operator>=(Iterator lhs, Iterator rhs) { !(lhs < rhs); }
}
See legacy requirements for random access iterators