C++: Proper way to iterate over STL containers

后端 未结 8 1483
灰色年华
灰色年华 2021-01-06 04:55

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 ite

8条回答
  •  忘掉有多难
    2021-01-06 05:45

    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::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::iterator theEnd = theContainer.end();
    
    for (::std::vector::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.

提交回复
热议问题