59

I have a vector of Student which has a field name.

I want to iterate over the vector.

void print(const vector<Student>& students)
    {
    vector<Student>::iterator it;
    for(it = students.begin(); it < students.end(); it++)
        {
            cout << it->name << endl;
        }
    }

This is apparently illegal in C++.

Please help.

unj2
  • 52,135
  • 87
  • 247
  • 375
  • 2
    Please read about prefix versus postfix increment operator. `it++` should be `++it`, and `it++` is needed in rare cases (i.e. when erasing while iterating). –  Feb 03 '11 at 19:10
  • 4
    Its fairly obvious what the issue is in this case. However, in the future you should include in your question the exact error message the compiler is giving you. – T.E.D. Feb 03 '11 at 19:13
  • @user405725: So... I see you do program in ++C! :-) – André Caldas Mar 10 '23 at 10:43

6 Answers6

76

You have two (three in C++11) options: const_iterators and indexes (+ "range-for" in C++11)

void func(const std::vector<type>& vec) {
  std::vector<type>::const_iterator iter;
  for (iter = vec.begin(); iter != vec.end(); ++iter)
    // do something with *iter

  /* or
  for (size_t index = 0; index != vec.size(); ++index)
    // do something with vec[index]

  // as of C++11
  for (const auto& item: vec)
    // do something with item
  */
}

You should prefer using != instead of < with iterators - the latter does not work with all iterators, the former will. With the former you can even make the code more generic (so that you could even change the container type without touching the loop)

template<typename Container>
void func(const Container& container) {
  typename Container::const_iterator iter;
  for (iter = container.begin(); iter != container.end(); ++iter)
    // work with *iter
}
eq-
  • 9,986
  • 36
  • 38
  • I am new to iterators. Can you please tell me which iterators do not like != and why? – unj2 Feb 04 '11 at 00:11
  • 4
    @kunjaan: Only random access iterators support ordering (`<`), others do not. For example, std::list has bi-directional iterators, that can only be compared for equality. – eq- Feb 04 '11 at 16:29
20

Use const_iterator instead. An iterator allows modification of the vector, so you can't get one from a const container.

Also, the idiomatic way to write this loop uses it != students.end() instead of < (though this should work on a vector).

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 2
    ...but if you ever decide to change to use a `list` or something similar instead, your code won't work. So use the `!=` form. – T.E.D. Feb 03 '11 at 19:11
9

C++11 style:

void print(const vector<Student>& students) {
    for(auto const& student : students) {
            cout << student.name << endl;
    }
}
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
3

Instead of vector<Student>::iterator, use vector<Student>::const_iterator.

Craig McQueen
  • 41,871
  • 30
  • 130
  • 181
user511274
  • 503
  • 4
  • 8
2
void print(const vector<Student>& students)
    {
    vector<Student>::const_iterator it; // const_iterator
    for(it = students.begin(); it != students.end(); it++)
        {
            cout << it->name << endl;
        }
    }
Kirill V. Lyadvinsky
  • 97,037
  • 24
  • 136
  • 212
2
void print(const vector<Student>& students)
    {
    for(auto it = students.begin(); it != students.end(); ++it)
        {
            cout << it->name << endl;
        }
    }
Blastfurnace
  • 18,411
  • 56
  • 55
  • 70