Re[4]: Remove_if или что-то ещё
От: Evgeny.Panasyuk Россия  
Дата: 19.07.13 12:03
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Есть другая тонкость.

К>remove_if не обязан помещать удалённые элементы в хвост — в отличие от partition.
К>То есть, может делать swap, move или даже копирующее присваивание.
К>А в хвосте оказывается произвольный мусор (валидные, но бесполезные элементы). И всё, что с ними остаётся сделать — это erase.

http://www.rsdn.ru/forum/cpp/5234995.1
Автор: Evgeny.Panasyuk
Дата: 19.07.13


К>Выгоднее будет написать unstable_remove / unstable_remove_if

[...]

я тоже думал сейчас сделать такой, но вошёл в цикл поиска нормального названия и не вышел, почему-то в голову лезло только "nonstable" — что казалось слишком некрасиво.

К>(скопипастил с cppereference.com и подправил две строки)


Копипастить нужно Степанова, например с SGI STL или с Notes — потому что, во-первых у него колличество операций оптимизировано, а во-вторых работает:
template<typename I, typename P>
/*
requires
(
    Mutable(I) && BidirectionalIterator(I) &&
    UnaryPredicate(P) && ValueType(I) == Domain(P)
)
*/
I unstable_remove_if(I first, I last, P p)
{
    while (true)
    {
        while (true)
            if (first == last)
                return first;
            else if (!p(*first))
                ++first;
            else
                break;
        --last;
        while (true)
            if (first == last)
                return first;
            else if (p(*last))
                --last;
            else
                break;
        *first = std::move(*last);
        ++first;
    }
}

Код же с cppereference.com на пустом range делает last-- (кстати, они его сами написали или откуда-то взяли?)
Re: Remove_if или что-то ещё
От: jinjik  
Дата: 19.07.13 12:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Точно понимаю, что это оптимизируется в нормальный вызов remove_if. Как лучше сделать? А с бустом?


Для boost::ptr_vector
class Currency {
...
};
typedef boost::ptr_vector<Currency> Currencies;
...
selectedCurrencies.erase_if([&indexPath](Currency &c) { return indexPath.row == c.getGroupOrder(); });
Re[4]: Remove_if или что-то ещё
От: Шахтер Интернет  
Дата: 19.07.13 15:15
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Есть другая тонкость.

К>remove_if не обязан помещать удалённые элементы в хвост — в отличие от partition.
К>То есть, может делать swap, move или даже копирующее присваивание.

Всё-таки move по-хорошему. Для простых типов -- просто копирование.

К>Выгоднее будет написать unstable_remove / unstable_remove_if


Если не лень написать свой алгоритм -- то да. Разница с partition -- move вместо swap.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.