1. C++ / Говнокод #14769

    +41

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    for (std::vector<SomeClass::SmartPtr>::iterator i = candidates.begin ();
               i != candidates.end (); )
          {
             if ((*i)->getArea ().intersect (thisArea))
             {
                // label is inside the area.
                ++i;
             }
             else
             {
                // label must be removed
                std::iter_swap (i, candidates.end () - 1);
                candidates.pop_back ();
             }
          }

    Не совсем ясны были мотивы человека, написавшего это. Этот код вообще не работает и не сразу и поймешь что тут к чему.

    Запостил: bes, 21 Февраля 2014

    Комментарии (7) RSS

    • candidates.erase(std::remove_if(candidates.begin(), 
                                      candidates.end(), 
                                      [&thisArea](SomeClass::Smartptr& i)
                                          {return !( i->getarea().intersect(thisArea) );} ), 
                       candidates.end())
      Как-то так. А почему не работает-то? Вроде ни итер_своп, ни поп_бак не должны инвалидировать итераторы.
      Ответить
      • http://ideone.com/61Lgv7
        Вот, для интов работает. Если я не пропустил нигде какой-то скрытый UB, значит проблема связана со спецификой SomeClass или SmartPtr
        Ответить
        • pop_back инвалидирует
          Ответить
          • The end iterator and any iterator, pointer and reference referring to the removed element are invalidated.
            Iterators, pointers and references referring to other elements that have not been removed are guaranteed to keep referring to the same elements they were referring to before the call. (c)
            Ответить
    • строки 11-13.

      я таким же трюком пользуюсь когда несортированый набор в векторе/массиве лежит. поиска быстрого нету - но там где это мне нужно 4х-5х экономия памяти по сравнению с std::set.

      и вот таким незамысловатым образом можно из несортированого вектора удалить элемент из середины за О(1): скопировать на его место последний элемент, размер вектора уменьшить на единицу.
      Ответить
    • - Ты с ума сошёл? - офонаревшими глазами я смотрел на радостно улыбающегося парня.
      Ответить

    Добавить комментарий