Iterate through a C++ Vector using a 'for' loop - c++

I am new to the C++ language. I have been starting to use vectors, and have noticed that in all of the code I see to iterate though a vector via indices, the first parameter of the for loop is always something based on the vector. In Java I might do something like this with an ArrayList:
for(int i=0; i < vector.size(); i++){
vector[i].doSomething();
}
Is there a reason I don't see this in C++? Is it bad practice?

The reason why you don't see such practice is quite subjective and cannot have a definite answer, because I have seen many of the code which uses your mentioned way rather than iterator style code.
Following can be reasons of people not considering vector.size() way of looping:
Being paranoid about calling size() every time in the loop
condition. However either it's a non-issue or it can be trivially
fixed
Preferring std::for_each() over the for loop itself
Later changing the container from std::vector to other one (e.g.
map, list) will also demand the change of the looping mechanism,
because not every container support size() style of looping
C++11 provides a good facility to move through the containers. That is called "range based for loop" (or "enhanced for loop" in Java).
With little code you can traverse through the full (mandatory!) std::vector:
vector<int> vi;
...
for(int i : vi)
cout << "i = " << i << endl;

The cleanest way of iterating through a vector is via iterators:
for (auto it = begin (vector); it != end (vector); ++it) {
it->doSomething ();
}
or (equivalent to the above)
for (auto & element : vector) {
element.doSomething ();
}
Prior to C++0x, you have to replace auto by the iterator type and use member functions instead of global functions begin and end.
This probably is what you have seen. Compared to the approach you mention, the advantage is that you do not heavily depend on the type of vector. If you change vector to a different "collection-type" class, your code will probably still work. You can, however, do something similar in Java as well. There is not much difference conceptually; C++, however, uses templates to implement this (as compared to generics in Java); hence the approach will work for all types for which begin and end functions are defined, even for non-class types such as static arrays. See here: How does the range-based for work for plain arrays?

Is there any reason I don't see this in C++? Is it bad practice?
No. It is not a bad practice, but the following approach renders your code certain flexibility.
Usually, pre-C++11 the code for iterating over container elements uses iterators, something like:
std::vector<int>::iterator it = vector.begin();
This is because it makes the code more flexible.
All standard library containers support and provide iterators. If at a later point of development you need to switch to another container, then this code does not need to be changed.
Note: Writing code which works with every possible standard library container is not as easy as it might seem to be.

The right way to do that is:
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
it->doSomething();
}
Where T is the type of the class inside the vector. For example if the class was CActivity, just write CActivity instead of T.
This type of method will work on every STL (Not only vectors, which is a bit better).
If you still want to use indexes, the way is:
for(std::vector<T>::size_type i = 0; i != v.size(); i++) {
v[i].doSomething();
}

Using the auto operator really makes it easy to use as one does not have to worry about the data type and the size of the vector or any other data structure
Iterating vector using auto and for loop
vector<int> vec = {1,2,3,4,5}
for(auto itr : vec)
cout << itr << " ";
Output:
1 2 3 4 5
You can also use this method to iterate sets and list. Using auto automatically detects the data type used in the template and lets you use it.
So, even if we had a vector of string or char the same syntax will work just fine

A correct way of iterating over the vector and printing its values is as follows:
#include<vector>
// declare the vector of type int
vector<int> v;
// insert elements in the vector
for (unsigned int i = 0; i < 5; ++i){
v.push_back(i);
}
// print those elements
for (auto it = v.begin(); it != v.end(); ++it){
std::cout << *it << std::endl;
}
But at least in the present case it is nicer to use a range-based for loop:
for (auto x: v) std::cout << x << "\n";
(You may also add & after auto to make x a reference to the elements rather than a copy of them. It is then very similar to the above iterator-based approach, but easier to read and write.)

There's a couple of strong reasons to use iterators, some of which are mentioned here:
Switching containers later doesn't invalidate your code.
i.e., if you go from a std::vector to a std::list, or std::set, you can't use numerical indices to get at your contained value. Using an iterator is still valid.
Runtime catching of invalid iteration
If you modify your container in the middle of your loop, the next time you use your iterator it will throw an invalid iterator exception.

Here is a simpler way to iterate and print values in vector.
for(int x: A) // for integer x in vector A
cout<< x <<" ";

With STL, programmers use iterators for traversing through containers, since iterator is an abstract concept, implemented in all standard containers. For example, std::list has no operator [] at all.

I was surprised nobody mentioned that iterating through an array with an integer index makes it easy for you to write faulty code by subscripting an array with the wrong index. For example, if you have nested loops using i and j as indices, you might incorrectly subscript an array with j rather than i and thus introduce a fault into the program.
In contrast, the other forms listed here, namely the range based for loop, and iterators, are a lot less error prone. The language's semantics and the compiler's type checking mechanism will prevent you from accidentally accessing an array using the wrong index.

don't forget examples with const correctness - can the loop modify the elements. Many examples here do not, and should use cont iterators. Here we assume
class T {
public:
T (double d) : _d { d } {}
void doSomething () const { cout << _d << endl; return; }
void changeSomething () { ++_d; return; }
private:
double _d;
};
vector<T> v;
// ...
for (const auto iter = v.cbegin(); iter != v.cend(); ++iter) {
iter->doSomething();
}
Note also, that with the C++11 notation, the default is to copy the element. Use a reference to avoid this, and/or to allow for original elements to be modified:
vector<T> v;
// ...
for (auto t : v) {
t.changeSomething(); // changes local t, but not element of v
t.doSomething();
}
for (auto& t : v) { // reference avoids copying element
t.changeSomething(); // changes element of v
t.doSomething();
}
for (const auto& t : v) { // reference avoids copying element
t.doSomething(); // element can not be changed
}

//different declaration type
vector<int>v;
vector<int>v2(5,30); //size is 5 and fill up with 30
vector<int>v3={10,20,30};
//From C++11 and onwards
for(auto itr:v2)
cout<<"\n"<<itr;
//(pre c++11)
for(auto itr=v3.begin(); itr !=v3.end(); itr++)
cout<<"\n"<<*itr;

int main()
{
int n;
int input;
vector<int> p1;
vector<int> ::iterator it;
cout << "Enter the number of elements you want to insert" << endl;
cin >> n;
for (int i = 0;i < n;i++)
{
cin >> input;
p1.push_back(input);
}
for(it=p1.begin();it!=p1.end();it++)
{
cout << *it << endl;
}
//Iterating in vector through iterator it
return 0;
}
conventional form of iterator

If you use
std::vector<std::reference_wrapper<std::string>> names{ };
Do not forget, when you use auto in the for loop, to use also get, like this:
for (auto element in : names)
{
element.get()//do something
}

Related

How should I loop over the elements of a C++ container in reverse order? [duplicate]

This question already has answers here:
Iterating C++ vector from the end to the beginning
(13 answers)
Closed 2 years ago.
Suppose I'm a newbie C++ programmer. I have a C++ container; say, a vector:
std::vector<int> vec { 12, 34, 56, 78 };
I know I can iterate over all of the elements with a simple loop:
for(std::vector<int>::size_type i = 0; i < vec.size(); i++) {
std::cout << vec[i] << '\n';
}
and maybe I've even learned a little about Modern C++, so I know I can use a ranged-for loop:
for(auto x : vec) {
std::cout << x << '\n';
}
But now, I want to iterate over the elements in reverse order. The range-based for loop won't work as such. With a plain loop, I have to be careful and avoid underflow, so perhaps something like this? :
for(std::vector<int>::size_type i = 0; i < vec.size(); i++) {
std::cout << vec[vec.size() - i] << '\n';
}
but - I don't like having the loop counter mean the opposite of what we're looking at. But if I started i at vec.size()-1, I would risk underflow after the last element. So I would need to do this, maybe?
for(std::vector<int>::size_type i = vec.size(); i > 0 ; i--) {
std::cout << vec[i - 1] << '\n';
}
well, that doesn't feel right either. What idioms should I use for reverse iteration, which are safe (i.e. difficult to get wrong) , aesthetically pleasing and reasonable terse?
Notes:
I tried to phrase the title to be as simple as possible (rather than saying "reverse-iterate a container").
Motivated by this question, where a naive reverse-iteration loop has a bug.
I do not want to make a copy of the container with the elements and reverse and iterate over that the usual way.
I didn't use auto& or const auto& in the loops above since newbie coders often don't know about them.
Well, first of all, about your two snippets: Part of the problem is that they're a bit bug prone for actual newbies - the integer underflow, off-by-one in the comparison, forgetting what i signifies and using it as a plain index etc. So I would definitely recommend something else. Also, those snippets may invoke vec.size() many times, which, if the compiler isn't optimizing well enough, would mean a bunch of redundant work.
Option 1: Use iterators
You can reverse-iterate over a container using a pair of iterators (std::rbegin and std::rend, and their constant variants) which represent the reversal of the container's order of elements. Here's what that looks like:
for(auto it = std::crbegin(vec); it != std::crend(vec); it++) {
std::cout << *it << '\n';
}
I made this option the first because it's (mostly) compatible with C++98. We didn't have std::rbegin() and std::crbegin() then, but we did have an rbegin() method for std::vector. std::crbegin() was introduced in C++11
Option 2: Using C++11 (and later) ranged-for loops
You can massage your container - without making a copy of it (although possibly with some payment of time), so that you can use the result in ranger for loop. The answers to this SO question describe several ways to do so, enabling the following code:
auto reverse_view = /* magic involving vec; and not making a copy */
for(auto x : reverse_view) {
std::cout << *it << '\n';
}
They involve either using an "infrastructural" library (namely Boost), or writing a few lines of code which return an iterator pair in an std::pair - which is enough for C++ to use in a ranged-for loop.
Option 3: Using ranged-for and C++20's ranges support
Finally, in C++20, this all becomes easier - with ranges support and std::ranges::reverse_view:
auto reverse_view = std::ranges::reverse_view{vec};
for (const auto& x : reverse_view) {
std::cout << x << '\n';
}
Performance note
Reverse-iterating can in some cases be expensive - because moving backwards, or finding the end of the container, is not always trivial or free. Think of a unidirectional list (where each element comes with a pointer to the next one) - whenever you want to go backwards, you need to traverse the whole list up to your current element to know where the previous element is located. Not all containers are like vectors...

Difference between vector::begin() and std::begin()

While iterating over a vector in c++, I noticed there is a begin() function in the standard library, and also a begin() as a member function of the vector class. What, if any, is the difference between the two, and which should be used over the other?
Example:
vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = numbers.begin(); i < numbers.end(); i++)
cout << *i << '\n';
vs:
vector<int> numbers;
//Code to put values in my vector
for (vector<int>::iterator i = std::begin(numbers); i < std::end(numbers); i++)
cout << *i << '\n';
std::begin() was added in C++11 to make it easier to write generic code (e.g. in templates). The most obvious reason for it is that plain C-style arrays do not have methods, hence no .begin(). So you can use std::begin() with C-style arrays, as well as STL-style containers having their own begin() and end().
If you're writing code which is not a template, you can ignore std::begin(); your fellow programmers would probably find it odd if you suddenly started using it everywhere just because it's new.
The implementation of std::begin() for vectors simply calls std::vector<T>::begin(), so there is no difference between the two in this exact case.
Where std::begin() comes into its own is in generic algorithms:
template<typename Container>
void my_algorithm(Container c) {
using std::begin;
using std::end;
auto const start = begin(c); // ADL will find the appropriate overload
auto const finish = end(c);
// ... rest of code ...
}

Why adding to vector does not work while using iterator?

I have two code sample, which do exactly same thing. One is in C++03 and C++11.
C++ 11
int main()
{
vector<int> v = {1,2,3};
int count = 0;
for each (auto it in v)
{
cout << it<<endl;
if (count == 0)
{
count++;
v.push_back(4);//adding value to vector
}
}
return 0;
}
C++ 03
int main()
{
vector<int> v = {1,2,3};
int count = 0;
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it<<endl;
if (count == 0)
{
count++;
v.push_back(4);//adding value to vector
}
}
return 0;
}
Both the codes are giving following exception.
Now when I see vector::end() implementation,
iterator end() _NOEXCEPT
{
// return iterator for end of mutable sequence
return (iterator(this->_Mylast, this));
}
Here, inline function clearly takes _Mylast to calculate end. So, when I add, it pointer will be incremented to next location, like _Mylast++. Why I am getting this exception?
Thanks.
A vector stores its elements in contiguous memory. If that memory block needs to be reallocated, iterators become invalid.
If you need to modify the vector's size while iterating, iterate by index instead of iterator.
Another option is to use a different container with a different iterator behavior, for example a list will allow you to continue iterating as you insert items.
And finally, (dare I suggest this?) if you know the maximum size your vector will grow to, .reserve() it before iterating over it. This will ensure it doesn't get reallocated during your loop. I am not sure if this behavior is guaranteed by the standard though (maybe someone can chime in); I would definitely not do it, considering iterating by index is perfectly safe.
Your push_back is invalidating the iterator you're using in the for loop, because the vector is reallocating its memory, which invalidates all iterators to elements of the vector.
The idiomatic solution for this is to use an insert_iterator, like the one you get from calling std::back_insterter on the vector. Then you can do:
#include <iostream>
#include <iterator>
#include <vector>
int main()
{
std::vector<int> v;
auto inserter = std::back_inserter(v);
for(int i=0; i<100; ++i)
inserter = i;
for(const auto item : v)
std::cout << item << '\n';
}
And it will ensure its own validity even through reallocation calls of the underlying container.
Live demo here.

c++ best way to use for loop

I have this question that runs in my mind...
I have a std::vector to iterate:
which is the best way (the faster) to iterate?
here is the code using an iterator:
// using the iterator
for( std::vector <myClass*>::iterator it = myObject.begin( ); it != myObject.end( ); it++ )
{
(*it)->someFunction( );
}
and here is 'normal' mode...
// normal loop
for( int i = 0; i < myObject.Size( ); i++ )
{
myObject[i]->someFunction( );
}
thanks for your suggestions!
None of the two will be any faster really, because on most implementations a vector<T>::iterator is just a typedef for T* and size is cached.
But doing ++it instead of it++ is a good habit. The latter involves creating a temporary.
for(std::vector <myClass*>::iterator it = myObject.begin( );
it != myObject.end( );
++it)
^^^^
On other containers such as map, list etc. with nontrivial iterators the difference between postincrement and preincrement might become noticable.
If you really care, you can find out: Just make a single source file with one function with that loop and look at the optimized assembly:
g++ -O2 -S -o ver1.s ver1.cpp
g++ -O2 -S -o ver2.s ver2.cpp
You can directly see the differences! I bet there are none.
That said, you should use the iterator pattern because it's idomatic, generic C++ and it gets you in the right mood -- plus, it works in far more general cases than just vectors! Write it like this:
typedef std::vector<MyClass*> myVec;
for (myVec::const_iterator it = v.begin(), end = v.end(); it != end; ++it)
{
const MyClass & x = **it;
/* ... */
}
In case you're curious, a vector iterator is most likely just going to be a native, raw pointer, so there's really nothing to fear in terms of efficiency, and a lot to be enjoyed from the self-explanatory, algorithmic style!
PS If you have C++0x, say it like this:
for (auto it = v.cbegin(), end = v.cend(); it != end; ++it)
// or
for (const MyClass * & i : v)
The first code will decompose into incrementing a pointer. The second one will increment an index, and index into the array. The first one can use slightly smaller instructions (and thus potentially be faster) assuming the compiler doesn't optimize the second into the first already. But it will be a trivial difference.
Iterators should be preferred, however, not because of speed but because you can then easily move the code to iterate any standard C++ container, not just vector.
However, you've got a few things to improve.
Don't use it++, but ++it. This can be very important in C++ because iterators can end up doing a little more work in post-increment which won't be optimized out as if the type were an int.
Don't constantly call end() or size(). For some iterator types and collections this might not be optimized out and can be very sub-optimal.
Use vector::size_type when you need an index into a vector. int is not guaranteed to be big enough, while size_type was made specifically for that.
So, the better ways to write these are:
// using the iterator
for(std::vector <myClass*>::iterator it = myObject.begin( ), end = myObject.end(); it != end; ++it)
{
(*it)->someFunction( );
}
// normal loop
for(std::vector <myClass*>::size_type i = 0, size = myObject.size(); i < size; ++i)
{
myObject[i]->someFunction( );
}
Here's what I use:
int s = vec.size();
for(int i=0;i<s;i++)
{
T &o = vec[i];
...
}
This loop has the following advantages over other approaches:
it always looks the same (unlike the hacks that change from i++ to ++i)
it's relatively short to write (compared to the iterator version)
the int indexes are useful in your public interface (unlike iterators)
it still always looks the same (unlike stdlib algorithms, where you need documentation to remember the parameters)
it's very old and thus widely used. (originally comes from book "The C programming language" aka K&R)
It doesn't give warnings on most compilers (unlike the loop that was used in the question)
It does have some disadvantages too:
some newer programmers doesn't like it because they think C ways are too old
in a const function, you might need to change it slightly to const T &o = vec[i]; or change the data member mutable
type T changes depending on the use
You can do this:
#include <iostream>
using namespace std;
int main() {
for (int i = 3; i > 0; i--) {
cout << i << "\n";
}
return 0;
}
source https://mockstacks.com/Cpp_For_Loop

C++: Proper way to iterate over STL containers

In my game engine project, I make extensive use of the STL, mostly of the std::string and std::vector classes.
In many cases, I have to iterate through them. Right now, the way I'm doing it is:
for( unsigned int i = 0; i < theContainer.size(); i ++ )
{
}
Am I doing it the right way?
If not, why, and what should I do instead?
Is size() really executed every loop cycle with this implementation? Would the performance loss be negligible?
C++11 has a new container aware for loop syntax that can be used if your compiler supports the new standard.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> vs;
vs.push_back("One");
vs.push_back("Two");
vs.push_back("Three");
for (const auto &s : vs)
{
cout << s << endl;
}
return 0;
}
You might want to look at the standard algorithms.
For example
vector<mylass> myvec;
// some code where you add elements to your vector
for_each(myvec.begin(), myvec.end(), do_something_with_a_vector_element);
where do_something_with_a_vector_element is a function that does what goes in your loop
for example
void
do_something_with_a_vector_element(const myclass& element)
{
// I use my element here
}
The are lots of standard algorithms - see http://www.cplusplus.com/reference/algorithm/ - so most things are supported
STL containers support Iterators
vector<int> v;
for (vector<int>::iterator it = v.begin(); it!=v.end(); ++it) {
cout << *it << endl;
}
size() would be re-computed every iteration.
For random-access containers, it's not wrong.
But you can use iterators instead.
for (string::const_iterator it = theContainer.begin();
it != theContainer.end(); ++it) {
// do something with *it
}
There are some circumstances under which a compiler may optimize away the .size() (or .end() in the iterator case) calls (e.g. only const access, function is pure). But do not depend on it.
Usually the right way to "iterate" over a container is using "iterators". Something like
string myStr = "hello";
for(string::iterator i = myStr.begin(); i != myStr.end(); ++i){
cout << "Current character: " << *i << endl;
}
Of course, if you aren't going to modify each element, it's best to use string::const_iterator.
And yes, size() gets called every time, and it's O(n), so in many cases the performance loss will be noticeable and it's O(1), but it's a good practice to calculate the size prior to the loop than calling size every time.
No, this is not the correct way to do it. For a ::std::vector or a ::std::string it works fine, but the problem is that if you ever use anything else, it won't work so well. Additionally, it isn't idiomatic.
And, to answer your other question... The size function is probably inline. This means it likely just fetches a value from the internals of ::std::string or ::std::vector. The compiler will optimize this away and only fetch it once in most cases.
But, here is the idiomatic way:
for (::std::vector<Foo>::iterator i = theContainer.begin();
i != theContainer.end();
++i)
{
Foo &cur_element = *i;
// Do stuff
}
The ++i is very important. Again, for ::std:vector or ::std::string where the iterator is basically a pointer, it's not so important. But for more complicated data structures it is. i++ has to make a copy and create a temporary because the old value needs to stick around. ++i has no such issue. Get into the habit of always using ++i unless you have a compelling reason not to.
Lastly, theContainer.end() will also be generally optimized out of existence. But you can force things to be a little better by doing this:
const ::std::vector<Foo>::iterator theEnd = theContainer.end();
for (::std::vector<Foo>::iterator i = theContainer.begin(); i != theEnd; ++i)
{
Foo &cur_element = *i;
// Do stuff
}
Of course, C++0x simplifies all of this considerably with a new syntax for for loops:
for (Foo &i: theContainer)
{
// Do stuff with i
}
These will work on standard fix-sized arrays as well as any type that defines begin and end to return iterator-like things.
Native for-loop (especially index-based) - it's C-way, not C++-way.
Use BOOST_FOREACH for loops.
Compare, for container of integers:
typedef theContainer::const_iterator It;
for( It it = theContainer.begin(); it != theContainer.end(); ++it ) {
std::cout << *it << std::endl;
}
and
BOOST_FOREACH ( int i, theContainer ) {
std::cout << i << std::endl;
}
But this is not perfect way. If you can do your work without loop - you MUST do it without loop. For example, with algorithms and Boost.Phoenix:
boost::range::for_each( theContainer, std::cout << arg1 << std::endl );
I understand that these solutions bring additional dependencies in your code, but Boost is 'must-have' for modern C++.
You're doing it OK for vectors, although that doesn't translate into the right way for other containers.
The more general way is
for(std::vector<foo>::const_iterator i = theContainer.begin(); i != theContainer.end; ++i)
which is more typing than I really like, but will become a lot more reasonable with the redefinition of auto in the forthcoming Standard. This will work on all standard containers. Note that you refer to the individual foo as *i, and use &*i if you want its address.
In your loop, .size() is executed every time. However, it's constant time (Standard, 23.1/5) for all standard containers, so it won't slow you down much if at all. Addition: the Standard says "should" have constant complexity, so a particularly bad implementation could make it not constant. If you're using such a bad implementation, you've got other performance issues to worry about.