CS253 Iterators
You have an array, and you want to traverse (walk through) it.
int a[] = {3141, 5926, 5358, 9793, 2384, 6264}; for (int i=0; i!=6; ++i) cout << a[i] << ' ';
3141 5926 5358 9793 2384 6264
a[i]
is the same as *(a+i)
.
i<6
, rather than i!=6
.
i++
rather than ++i
.
Let’s do it with a pointer:
int a[] = {3141, 5926, 5358, 9793, 2384, 6264}; for (int *p = &a[0]; p != &a[6]; ++p) cout << *p << ' ';
3141 5926 5358 9793 2384 6264
a[i]
(addition+indirection) we have just indirection.
vector
traversalYou can traverse a vector
in the same way:
vector<int> a = {3141, 5926, 5358, 9793, 2384, 6264}; for (int *p = &a[0]; p != &a[6]; ++p) cout << *p << ' ';
3141 5926 5358 9793 2384 6264
or, avoiding the magic number 6:
vector<int> a = {3141, 5926, 5358, 9793, 2384, 6264}; for (int *p = &a[0]; p != &a[a.size()]; ++p) cout << *p << ' ';
3141 5926 5358 9793 2384 6264
vector<int> a = {3141, 5926, 5358, 9793, 2384, 6264}; for (vector<int>::iterator it = a.begin(); it != a.end(); ++it) cout << *it << ' ';
3141 5926 5358 9793 2384 6264
iterator
is a type provided by the templated vector
class.
int *
, might not
*
works on it
++
works on it
.begin()
to it
.end()
auto
is your friendThis is prettier:
vector<int> a = {3141, 5926, 5358, 9793, 2384, 6264}; for (auto it = a.begin(); it != a.end(); ++it) cout << *it << ' ';
3141 5926 5358 9793 2384 6264
for
loopThis is exactly the same:
vector<int> a = {3141, 5926, 5358, 9793, 2384, 6264}; for (auto v : a) cout << v << ' ';
3141 5926 5358 9793 2384 6264
The for
loop is defined to use .begin()
and .end()
,
just as the previous code.
The same iterator code works for all STL containers.
forward_list<char> l = {'a', 'c', 'k', 'J'}; for (auto it = l.begin(); it != l.end(); ++it) cout << *it << ' ';
a c k J
unordered_set<char> u = {'a', 'c', 'k', 'J'}; for (auto it = u.begin(); it != u.end(); ++it) cout << *it << ' ';
J c k a
set<char> s = {'a', 'c', 'k', 'J'}; for (auto it = s.begin(); it != s.end(); ++it) cout << *it << ' ';
J a c k
iterator
typeset<int>::iterator
?
int *
, that’s for sure!
list<int>::iterator
and unordered_set<int>::iterator
.
operator++
is overloaded.
list
, set
, unordered_set
)
++
, --
, ==
, !=
, *
, ->
, =
std::array
, vector
, string
)
++
, --
,
+=
int, -=
int,
+
int, -
int,
iter-
iter,
==
, !=
,
<
, <=
,
>
, >=
,
*
, ->
, =
forward_list
)
++
, ==
, !=
, *
, ->
, =
begin()
& end()
.begin()
is, conceptually, a pointer to the
first element of the container.
.end()
is, conceptually, a pointer one past
the end of the container.
string s = "bonehead"; cout << "First character: " << *s.begin() << '\n'; cout << "This is wrong: " << *s.end() << '\n';
First character: b This is wrong: ␀
string s = "genius"; cout << "First character: " << *s.begin() << '\n'; cout << "Last character: " << *(s.end()-1) << '\n';
First character: g Last character: s
.front()
& .back()
Some containers have .front()
and .back()
, which return
references to the first and last elements.
list<double> c = {1.2, 3.4, 5.6}; cout << "First: " << c.front() << '\n'; cout << "Last: " << c.back() << '\n';
First: 1.2 Last: 5.6
These are not iterators.
list<string> l = {"kappa", "alpha", "gamma"}; for (auto it = l.begin(); it < l.end(); ++it) cout << *it << ' ';
c.cc:2: error: no match for 'operator<' in 'it < l.std::__cxx11::list<std::__cxx11::basic_string<char> >::end()' (operand types are 'std::_List_iterator<std::__cxx11::basic_string<char> >' and 'std::__cxx11::list<std::__cxx11::basic_string<char> >::iterator' {aka 'std::_List_iterator<std::__cxx11::basic_string<char> >'})
list<string> l = {"kappa", "alpha", "gamma"}; for (auto it = l.begin(); it != l.end(); ++it) cout << *it << ' ';
kappa alpha gamma
set<>::iterator
is a BidirectionalIterator, not a RandomAccessIterator,
and so <
isn’t defined. What would it compare? The addresses of the
linked list nodes? That’s not useful.
All containers accept a pair of iterators as ctor arguments. These do not have to be iterators for the same type of container.
string today = "2024-11-22"; cout << today << '\n'; multiset<char> ms(today.begin(), today.end()); for (char c : ms) cout << c;
2024-11-22 --01122224
string today = "2024-11-22"; cout << today << '\n'; string year(today.begin(), today.begin()+4); for (char c : year) cout << c;
2024-11-22 2024
Modified: 2017-04-04T17:43 User: Guest Check: HTML CSSEdit History Source |
Apply to CSU |
Contact CSU |
Disclaimer |
Equal Opportunity Colorado State University, Fort Collins, CO 80523 USA © 2015 Colorado State University |