|
-
March 6th, 2006, 03:26 AM
#1
iterate through std::vector ?
As I see in C++ books, all of them using != operator to check that the vector is end or not.
example:
Code:
std::vector<int>::iterator itr;
for ( itr = vec.begin(); itr != vec.end(); ++itr )
Is it possible if we use itr < vec.end() instead ????
-
March 6th, 2006, 03:52 AM
#2
Re: iterate through std::vector ?
You shouldn't even if it works. This is because different implementation of STLs may choose to return different values to indicate the end.
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
March 6th, 2006, 03:55 AM
#3
Re: iterate through std::vector ?
In addition, it will not work for container like list and map because they are not using contiguous memory.
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
March 6th, 2006, 03:58 AM
#4
Re: iterate through std::vector ?
Code:
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
int main()
{
vector< int> vec;
vec.push_back( 1 );
vec.push_back( 2 );
vec.push_back( 3 );
std::vector<int>::iterator itr;
for ( itr = vec.begin(); itr < vec.end(); ++itr )
{
cout << *itr << endl;
}
return 0;
}
This code will output the vector contents correctly. vec.begin(), returns _First, and vec.end() returns _Last. As vector is a sequential container, so iterating it the way you want, will work here, but as Kheun stated that you shouldn't adopt this practice, as some other container may not work like that, which kills the reason to use standard practices at the first place.
-
March 6th, 2006, 04:46 AM
#5
Re: iterate through std::vector ?
 Originally Posted by Kheun
You shouldn't even if it works. This is because different implementation of STLs may choose to return different values to indicate the end.
Not sure, this is correct. As "iter-n" is defined for random access iterators (e.g. vector::iterator), your statement would mean, that end()-1 has not defined behavior (assuming there is at least one element in the vector). I don't think that's true.
So I would state, that using it<end() is safe to use for std::vector, but it is bad practice due to the reason that it will not work with other containers.
-
March 6th, 2006, 05:11 AM
#6
Re: iterate through std::vector ?
May be I am wrong but for assumption that "iter < end()", it requires the end() to greater than the rest of the valid iterator range. Since we can't take for granted that iterator in vector is being implemented as pointer, I don't think we can assume "iter < end()" is always true. It's all dependent on how the vendor choose to implement it.
I am not sure what's the correct behavior. Probably someone with the C++ Standard can enlighten me.
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
March 6th, 2006, 05:41 AM
#7
Re: iterate through std::vector ?
Looking through section 23.1 of the C++ Standard (ISO/IEC 14882:2003), it seems that part of the container requirements specifies that for a container a, a.size() has operational semantics of "a.end()-a.begin()", and "begin() returns an iterator referring to the first element in the container. end() returns an iterator which is the past-the-end value for the container. If the container is empty, then begin() == end();"
That seems to guarantee that a.end() returns an iterator exactly one past the end value for container a. If not, it may be possible that a.size() == (a.end() - a.begin()) evaluates to false.
-
March 6th, 2006, 05:57 AM
#8
Re: iterate through std::vector ?
Found the following example from Josuttis book:
Code:
// Iterate through every second element
for (vector<int>::iterator it = v.begin(); it < v.end(); it += 2 )
So that seems to confirm that it is safe.
-
March 6th, 2006, 06:23 AM
#9
Re: iterate through std::vector ?
There's more to it, I think. For iterators, operator< is only defined for random access iterators, so while it may be safe in Josuttis' example, using operator!= is better in that it applies for all input iterators. In treuss' words, "it is bad practice due to the reason that it will not work with other containers" (that dont support random access iterators).
-
March 6th, 2006, 07:58 AM
#10
Re: iterate through std::vector ?
 Originally Posted by laserlight
For iterators, operator< is only defined for random access iterators, so while it may be safe in Josuttis' example, using operator!= is better in that it applies for all input iterators.
The example will not work for containers which provide bidrectional iterators only, as +=(int) is not defined for those, and using != instead of < max actually result in a program crash if the number of elements is odd.
-
March 6th, 2006, 07:42 PM
#11
Re: iterate through std::vector ?
Thank guys!
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
March 6th, 2006, 09:16 PM
#12
Re: iterate through std::vector ?
I've heard that operator < only works with random-access iterators, whereas != works with other iterator types. But in this case, vector is not random access but why when we use operator <, it works.
-
March 6th, 2006, 09:52 PM
#13
Re: iterate through std::vector ?
See the quote from MSDN.
The STL vector class is a template class of sequence containers that arrange elements of a given type in a linear arrangement and allow fast random access to any element. They should be the preferred container for a sequence when random-access performance is at a premium.
quoted from C++ Coding Standards:
KISS (Keep It Simple Software):
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
Avoid magic number:
Programming isn't magic, so don't incant it.
-
March 7th, 2006, 03:29 AM
#14
Re: iterate through std::vector ?
 Originally Posted by Butterfly
I've heard that operator < only works with random-access iterators, whereas != works with other iterator types. But in this case, vector is not random access but why when we use operator <, it works.
std::vector is a random access container.
And std::vector::iterator is a random access iterator.
 Originally Posted by treuss
The example will not work for containers which provide bidrectional iterators only, as +=(int) is not defined for those, and using != instead of < max actually result in a program crash if the number of elements is odd.
It is less likely to crash with <, but it may also crash.
Because adding two to an iterator equal to end()-1, may crash or yield an invalid iterator (it is like incrementing end()).
With trivial implementations of vector, it is unlikely (except if the vector has a max address equal to 2^32-1).
But, with std: eque it is very likely to happen.
"inherit to be reused by code that uses the base class, not to reuse base class code", Sutter and Alexandrescu, C++ Coding Standards.
Club of lovers of the C++ typecasts cute syntax: Only recorded member.
Out of memory happens! Handle it properly!
Say no to g_new()!
-
March 7th, 2006, 04:12 AM
#15
Re: iterate through std::vector ?
 Originally Posted by SuperKoko
It is less likely to crash with <, but it may also crash.
Because adding two to an iterator equal to end()-1, may crash or yield an invalid iterator (it is like incrementing end()).
With trivial implementations of vector, it is unlikely (except if the vector has a max address equal to 2^32-1).
But, with std:  eque it is very likely to happen.
Good point 
I actually quoted wrongly, the example is
Code:
for (pos = coll.begin(); pos < coll.end()-1; pos += 2)
and Josuttis explicitly stated that coll need to contain at least one argument for coll.end()-1 to be defined.
One should never close a book and then quote from it .
Last edited by treuss; March 7th, 2006 at 04:28 AM.
Reason: Typo
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|