Is Iterator initialization inside for loop considered bad style, and why?

前端 未结 13 1463
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-05 19:37

Typically you will find STL code like this:

for (SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin(); Iter != m_SomeMemberContainerVar.end         


        
相关标签:
13条回答
  • 2021-02-05 19:55

    If you wrap your code into lines properly, the inline form would be equally readable. Besides, you should always do the iterEnd = container.end() as an optimization:

    for (SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin(),
        IterEnd = m_SomeMemberContainerVar.end();
        Iter != IterEnd;
        ++Iter)
    {
    }
    

    Update: fixed the code per paercebal's advice.

    0 讨论(0)
  • 2021-02-05 19:59

    No, it's a bad idea to get a hold on iter.end() before the loop starts. If your loop changes the container then the end iterator may be invalidated. Also, the end() method is guaranteed to be O(1).

    Premature optimization is the root of all evil.

    Also, the compiler may be smarter than you think.

    0 讨论(0)
  • 2021-02-05 20:01

    I don't think it's bad style at all. Just use typedefs to avoid the STL verbosity and long lines.

    typedef set<Apple> AppleSet;
    typedef AppleSet::iterator  AppleIter;
    AppleSet  apples;
    
    for (AppleIter it = apples.begin (); it != apples.end (); ++it)
    {
       ...
    }
    

    Spartan Programming is one way to mitigate your style concerns.

    0 讨论(0)
  • 2021-02-05 20:01

    I find the second option more readable, as you don't end up with one giant line. However, Ferruccio brings up a good point about the scope.

    0 讨论(0)
  • 2021-02-05 20:04

    I would usually write:

    SomeClass::SomeContainer::iterator Iter = m_SomeMemberContainerVar.begin(),
                                       IterEnd = m_SomeMemberContainerVar.end();
    
    for(...)
    
    0 讨论(0)
  • 2021-02-05 20:05

    Another alternative is to use a foreach macro, for example boost foreach:

    BOOST_FOREACH( ContainedType item, m_SomeMemberContainerVar )
    {
       mangle( item );
    }
    

    I know macros are discouraged in modern c++, but until the auto keyword is widely available this is the best way I've found to get something that is concise and readable, and still completely typesafe and fast. You can implement your macro using whichever initialization style gets you better performance.

    There's also a note on the linked page about redefining BOOST_FOREACH as foreach to avoid the annoying all caps.

    0 讨论(0)
提交回复
热议问题