99

I'm very new to C++ and struggling to figure out how I should iterate through a list of objects and access their members.

I've been trying this where data is a std::list and Student a class.

std::list<Student>::iterator<Student> it;
for (it = data.begin(); it != data.end(); ++it) {
    std::cout<<(*it)->name;
}

and getting the following error:

error: base operand of ‘->’ has non-pointer type ‘Student’
1
  • 4
    First you need to read more about how to declare iterator variables. Hint: They are not templates. Secondly, while the iterator can in some ways be treated as a pointer, once you dereference it it's not longer a "pointer" but a value. Commented Mar 8, 2014 at 12:42

5 Answers 5

167

You're close.

std::list<Student>::iterator it;
for (it = data.begin(); it != data.end(); ++it){
    std::cout << it->name;
}

Note that you can define it inside the for loop:

for (std::list<Student>::iterator it = data.begin(); it != data.end(); ++it){
    std::cout << it->name;
}

And if you are using C++11 then you can use a range-based for loop instead:

for (auto const& i : data) {
    std::cout << i.name;
}

Here auto automatically deduces the correct type. You could have written Student const& i instead.

Sign up to request clarification or add additional context in comments.

4 Comments

For the C++11 version, what s the maximum number of elements before a possible internal loop indice is overflown if any? I m talking about Visual Studio and gcc on Linux.
@user2284570 There isn't any loop-index involved, only iterators.
@Deduplicator I was meaning internally by the compiler.
Excuse me, both std::cout<<(*it).name; and std::cout<<it->name; will work, right? Iterator can be regarded as pointer to the element.
26

Since C++ 11, you could do the following:

for(const auto& student : data)
{
  std::cout << student.name << std::endl;
}

4 Comments

Is const mandatory in range-based loop or is avoiding it a bad habbit?
It's a best-practice to prevent you (or whoever modifies it after you) from changing the contents of the vector as it's iterating. If you're implementing a transformative function, you may want to mutate the vector and therefore drop the const. But it's typically not recommended to write code that does that in most industry standards.
For the C++11 version, what s the maximum number of elements before a possible internal loop indice is overflown if any? I m talking about Visual Studio and gcc on Linux.
@user2284570 To my knowledge, you'll be limited to the maximum value of std::vector<T>::size_type, which is 2^64 / sizeof(T) (that is, the maximum number of objects that can be represented in the address space of memory. This is also why you shouldn't use STL containers to replace database in some situations.
5

If you add an #include <algorithm> then you can use the for_each function and a lambda function like so:

for_each(data.begin(), data.end(), [](Student *it) 
{
    std::cout<<it->name;
});

You can read more about the algorithm library at https://en.cppreference.com/w/cpp/algorithm

and about lambda functions in cpp at https://learn.microsoft.com/en-us/cpp/cpp/lambda-expressions-in-cpp?view=vs-2019

Comments

4

It is also worth to mention, that if you DO NOT intent to modify the values of the list, it is possible (and better) to use the const_iterator, as follows:

for (std::list<Student>::const_iterator it = data.begin(); it != data.end(); ++it){
    // do whatever you wish but don't modify the list elements
    std::cout << it->name;
}

1 Comment

Since C++11 we have cbegin() and cend().
3

-> it works like pointer u don't have to use *

for( list<student>::iterator iter= data.begin(); iter != data.end(); iter++ )
cout<<iter->name; //'iter' not 'it'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.