How can I avoid “for” loops with an “if” condition inside them with C++?

前端 未结 13 1821
滥情空心
滥情空心 2021-01-30 03:31

With almost all code I write, I am often dealing with set reduction problems on collections that ultimately end up with naive \"if\" conditions inside of them. Here\'s a simple

13条回答
  •  独厮守ぢ
    2021-01-30 04:13

    The idea of avoiding

    for(...)
        if(...)
    

    constructs as an antipattern is too broad.

    It is completely fine to process multiple items that match a certain expression from inside a loop, and the code cannot get much clearer than that. If the processing grows too large to fit on screen, that is a good reason to use a subroutine, but still the conditional is best placed inside the loop, i.e.

    for(...)
        if(...)
            do_process(...);
    

    is vastly preferable to

    for(...)
        maybe_process(...);
    

    It becomes an antipattern when only one element will match, because then it would be clearer to first search for the element, and perform the processing outside of the loop.

    for(int i = 0; i < size; ++i)
        if(i == 5)
    

    is an extreme and obvious example of this. More subtle, and thus more common, is a factory pattern like

    for(creator &c : creators)
        if(c.name == requested_name)
        {
            unique_ptr obj = c.create_object();
            obj.owner = this;
            return std::move(obj);
        }
    
    
    

    This is hard to read, because it isn't obvious that the body code will be executed once only. In this case, it would be better to separate the lookup:

    creator &lookup(string const &requested_name)
    {
        for(creator &c : creators)
            if(c.name == requested_name)
                return c;
    }
    
    creator &c = lookup(requested_name);
    unique_ptr obj = c.create_object();
    

    There is still an if within a for, but from the context it becomes clear what it does, there is no need to change this code unless the lookup changes (e.g. to a map), and it is immediately clear that create_object() is called only once, because it is not inside a loop.

    提交回复
    热议问题