CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Jun 2005
    Posts
    67

    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 ????

  2. #2
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    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.

  3. #3
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    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.

  4. #4
    Ejaz's Avatar
    Ejaz is offline Elite Member Power Poster
    Join Date
    Jul 2002
    Location
    Lahore, Pakistan
    Posts
    4,211

    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.

  5. #5
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: iterate through std::vector ?

    Quote 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.

  6. #6
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    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.

  7. #7
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.

  8. #8
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    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.

  9. #9
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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).

  10. #10
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: iterate through std::vector ?

    Quote 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.

  11. #11
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    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.

  12. #12
    Join Date
    Jun 2005
    Posts
    67

    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.

  13. #13
    Join Date
    Oct 2002
    Location
    Singapore
    Posts
    3,128

    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.

  14. #14
    Join Date
    Feb 2005
    Location
    Normandy in France
    Posts
    4,590

    Re: iterate through std::vector ?

    Quote 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.

    Quote 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()!

  15. #15
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: iterate through std::vector ?

    Quote 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

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured