В C ++ разрешено ли удалять объекты из списка & lt; Pointer & gt; :: unique

У нас есть унаследованный код, который возвращает списки необработанных указателей огромного размера для кучи выделенных объектов (мы не можем использовать интеллектуальные указатели), и мы удалим дубликаты из списка, а также удалим их из кучи.

На данный момент, как советует гуру, я хотел бы попробовать 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;
}) ;

Обновление № 1

Объяснение Майка было самым полезным, но сейчас мы используем такое решение:

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() );
}

4

Решение

Нет, нет гарантии, что это четко определено. unique не указан полностью, чтобы гарантировать, что это последний раз, когда b передается в предикат, поэтому возможно, что удаленный указатель может быть использован позже.

Я удивлен, что это работает для вас, так как спецификация для b быть первым из двух элементов, который будет сохранен, если оба будут удалены.

Я бы предложил хранить либо сами объекты, либо unique_ptr<Val> если вам действительно нужно, чтобы они были динамическими, чтобы они всегда уничтожались автоматически при удалении. Понятия не имею, почему вы говорите: «мы не можем использовать умные указатели»; они будут иметь гораздо больше смысла, чем прыгать через обручи, чтобы оставить ваш прежний код без изменений.

1

Другие решения


По вопросам рекламы [email protected]