As I see in C++ books, all of them using != operator to check that the vector is end or not.
example:
Is it possible if we use itr < vec.end() instead ????Code:std::vector<int>::iterator itr;
for ( itr = vec.begin(); itr != vec.end(); ++itr )
Printable View
As I see in C++ books, all of them using != operator to check that the vector is end or not.
example:
Is it possible if we use itr < vec.end() instead ????Code:std::vector<int>::iterator itr;
for ( itr = vec.begin(); itr != vec.end(); ++itr )
You shouldn't even if it works. This is because different implementation of STLs may choose to return different values to indicate the end.
In addition, it will not work for container like list and map because they are not using contiguous memory.
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.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;
}
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.Quote:
Originally Posted by Kheun
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.
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.
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.
Found the following example from Josuttis book:
So that seems to confirm that it is safe.Code:// Iterate through every second element
for (vector<int>::iterator it = v.begin(); it < v.end(); it += 2 )
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).
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.Quote:
Originally Posted by laserlight
Thank guys! :thumb:
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.
See the quote from MSDN.
Quote:
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.
std::vector is a random access container.Quote:
Originally Posted by Butterfly
And std::vector::iterator is a random access iterator.
It is less likely to crash with <, but it may also crash.Quote:
Originally Posted by treuss
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::deque it is very likely to happen.
Good point :thumb:Quote:
Originally Posted by SuperKoko
I actually quoted wrongly, the example isand Josuttis explicitly stated that coll need to contain at least one argument for coll.end()-1 to be defined.Code:for (pos = coll.begin(); pos < coll.end()-1; pos += 2)
One should never close a book and then quote from it ;).