在C++中,是否允许删除列表<Pointer>::唯一

In C++, is it allowed to delete objects in list<Pointer>::unique

本文关键字:lt 列表 Pointer 唯一 gt 删除 C++ 是否 许删除      更新时间:2023-10-16

我们有遗留代码,它返回了大量原始指针列表,以堆分配的对象(我们不能使用智能指针(,我们将从列表中删除重复项并从堆中删除它们。

现在,正如大师们所建议的那样,我想尝试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

Mike的解释是最有帮助的,但现在我们正在使用这样的解决方案:

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>,如果你真的需要它们是动态的,这样它们总是在删除时自动销毁。我不知道你为什么说"我们不能使用智能指针";它们比跳过箍来保持旧代码不变更有意义。