CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jun 2009
    Posts
    76

    Which practice of iteration through containers is preferred

    In the "real world" what kind of loop do most people use to iterate through a container like a vector.

    A loop like this...
    Code:
    for (int i = 0; i < v.size(); ++i) {
        // do whatever
    }
    Or like this...
    Code:
    for (vector<T>::iterator i = v.begin(); i != v.end(); ++i) {
        // do whatever
    }
    In addition to this question, I'm also wondering what's preferred in terms of output of a container. Iterating through its elements (like shown above) or using the copy algorithm with a stream iterator like this.

    Code:
    ostream_iterator<T> os(cout);
    copy(v.begin(), v.end(), os);
    Just some general coding practice questions for those in the industry. Any information is appreciated. Thanks.

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Which practice of iteration through containers is preferred

    For vectors specifically, I usually use an integer index simply because it's quicker to type. That may change once the "auto" keyword is repurposed in C++0x.

    Of course, any time the container type is templated and thus unknown, you have to use iterators.

  3. #3
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Which practice of iteration through containers is preferred

    I always use iterators as if my life depended on it. It takes a bit more to write, and it takes a bit of time to learn to use, but the benefits are high.

    Why? Static type safety and out of bounds protection.

    example:

    Code:
    for ( int i = 0 ; i <= vect1.size() ; ++i)
    {
        for ( int j = 0 ; j <= vect2.size() ; ++j)
        {
            vect3.pushback(vect2[i]+vect1[j]);
        }
    }
    In the above example, there are two problems. One: index out of bounds when i == size. Also, i describes indexes of vect1, but writing vect2[i] is completly legal!

    Compare with this:
    Code:
    std::vector<int>::const_iterator it1 = vect1.begin();
    const std::vector<int>::const_iterator it1end = vect1.end();
    for ( ; it1 != it1end ; ++it1 )
    {
        std::vector<int>::const_iterator it2 = vect2.begin();
        const std::vector<int>::const_iterator it2end = vect2.end();
        for ( ; it2 != it2end ; ++it2 )
        {
            vect3.pushback(*it1 + *it2);
        }
    }
    Now here, inside the loop, the objects *it1 and *it2 are perfectly defined. You never have to worry about i,j, or even k,m and n (for really embedded loops). You can't mess up. Also, while at first it might look like writing the loop is longer, it is also perfectly standardized to any container.

    I have a blank loop "template" which I copy paste at my work, like this.

    Code:
    CNTNR::const_iterator it = OBJ.begin();
    const CNTNR::const_iterator itEnd = OBJ.end();
    for ( ; it != itEnd ; ++it )
    {
        
    }
    Just replace CNTNR with your container type, and OBJ with your actual object. Notice you don't even have to touch the for part. it is always "stop at itEnd"

  4. #4
    Join Date
    Oct 2005
    Location
    England
    Posts
    803

    Re: Which practice of iteration through containers is preferred

    Quote Originally Posted by Lindley View Post
    For vectors specifically, I usually use an integer index simply because it's quicker to type. That may change once the "auto" keyword is repurposed in C++0x.
    I think C++0x also includes a for each implementation which will be even quicker to type.
    Rich

    Visual Studio 2010 Professional | Windows 7 (x64)
    Ubuntu

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

    Re: Which practice of iteration through containers is preferred

    Quote Originally Posted by trikker
    I'm also wondering what's preferred in terms of output of a container. Iterating through its elements (like shown above) or using the copy algorithm with a stream iterator like this.
    The use of std::copy would be more descriptive. Of course, if you create another function specifically to output the elements, that would be be even more descriptive, with that function being implemented with std::copy.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: Which practice of iteration through containers is preferred

    I normally use the "most advanced" method that will leave the code readable. That is, if I need to get the sum of the values in a vector e.g., I'll use std::accumulate. With more complex operations having a function object can obfuscate code, so then I'll likely use iterators, but sometimes also BOOST_FOR_EACH. The latter is especially nice when you have a container of pointers. Instead of writing
    Code:
    // typedef ... Iter
    for (Iter it = my_container.begin(), end = my_container.end(); it != end; ++it) {
        (*it)->DoSomething();
    }
    you can write
    // typedef ... ValueType
    BOOST_FOR_EACH (ValueType ptr, my_container) {
    ptr->DoSomething();
    }
    [/code]
    This can be a lot easier to read.

    However, when I either need an index of an element or when I need to access elements from multiple vectors of the same size, I'll use a for loop with an index, because I find that is the best way to keep the code readable. Having more than one iterator in one or more nested loops is generally confusing, I find.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    May 2009
    Posts
    2,413

    Re: Which practice of iteration through containers is preferred

    Quote Originally Posted by trikker View Post
    In the "real world" what kind of loop do most people use to iterate through a container like a vector.
    You should know that in the "real world" most things are done the wrong way. Instead you should aim at doing things the right way according to time-tested principles.

    One such principle is to use the highest possible abstraction available. This means that you "scan" the container assuming as little as possible about the actual container.

  8. #8
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Which practice of iteration through containers is preferred

    Quote Originally Posted by trikker View Post
    In the "real world" what kind of loop do most people use to iterate through a container like a vector.
    It depends.
    If I have a function that takes a pair of iterators then I may usually don't bother with a for loop and either use an STL algorithm or a simple while loop.

    Code:
    void Function(vector<int>::iterator begin, const vector<int>::iterator &end)
    {
        while (begin != end)
        {
            // Dereference 'begin' and do something.
            ++begin;
        }
    }
    As mentioned above, using iterators means that a templated function can be used on any container that is 'iterateable'.

    Code:
    template typename <TIterator>
    void Function(TIterator begin, const TIterator &end)
    {
        while (begin != end)
        {
            // Dereference 'begin' and do something.
            ++begin;
        }
    }
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

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