У нас есть унаследованный код, который возвращает списки необработанных указателей огромного размера для кучи выделенных объектов (мы не можем использовать интеллектуальные указатели), и мы удалим дубликаты из списка, а также удалим их из кучи.
На данный момент, как советует гуру, я хотел бы попробовать std :: list :: unique (или forward_list :: unique) вместо алгоритма std :: unique.
Я прочитал в http://en.cppreference.com/w/cpp/container/list/unique что в пределах «уникального» предиката мы не должны изменять объекты, поэтому безопасно ли по термину стандарт удалять «собирающиеся быть удаленными» объекты в list :: unique?
И если да, то какой объект в list :: unique должен рассматриваться как дубликат? В реализации GNU ‘B’ будет удален, но в http://www.cplusplus.com/reference/list/list/unique/ написано, что в pred (i, i-1), элемент i будет удален, так ли это поведение указано стандартом?
Этот код (работает в gcc) правильный с точки зрения стандарта или UB?
List.sort( [] (const Val *a, const Val *b) {
return *a < *b;
});
List.unique([] (const Val *a, const Val *b) {
if (*a == *b) {
delete b; // (1) working in gcc 4.6
// or (2) delete a (elsewhere)?
return true;
}
return false;
}) ;
Объяснение Майка было самым полезным, но сейчас мы используем такое решение:
struct RawPtrEq {
bool operator()(const Val a, const Val b) { return *a == *b;}
};
auto it = adjacent_find( begin(List), end(List), RawPtrEq() );
while(it != end(li)) {
delete *it;
it = List.erase(it);
it = adjacent_find( it, end(List), RawPtrEq() );
}
Нет, нет гарантии, что это четко определено. unique
не указан полностью, чтобы гарантировать, что это последний раз, когда b
передается в предикат, поэтому возможно, что удаленный указатель может быть использован позже.
Я удивлен, что это работает для вас, так как спецификация для b
быть первым из двух элементов, который будет сохранен, если оба будут удалены.
Я бы предложил хранить либо сами объекты, либо unique_ptr<Val>
если вам действительно нужно, чтобы они были динамическими, чтобы они всегда уничтожались автоматически при удалении. Понятия не имею, почему вы говорите: «мы не можем использовать умные указатели»; они будут иметь гораздо больше смысла, чем прыгать через обручи, чтобы оставить ваш прежний код без изменений.