c++ - 在 C++ 中,是否允许删除 list<Pointer>::unique 中的对象

标签 c++ list unique duplicate-removal forward-list

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

现在,正如专家建议的那样,我想尝试 std::list::unique(或 forward_list::unique)而不是算法 std::unique。

我读过 http://en.cppreference.com/w/cpp/container/list/unique在'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>如果你真的需要它们是动态的,那么它们总是在移除时自动销毁。我不知道你为什么说“我们不能使用智能指针”;它们比跳过篮球让您的遗留代码保持不变更有意义。

关于c++ - 在 C++ 中,是否允许删除 list<Pointer>::unique 中的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27253807/

相关文章:

c++ - 基类中使用 this 指针的模板函数

c++ - 数字文字运算符错误

c# - 在 C# 中迭代​​泛型列表时出现性能问题

ruby-on-rails - Rails : Append number to permalink,(如果永久链接已被占用)

r - 如何使用 DPLYR 汇总一列中组的唯一值?

python - 从 pandas 系列列表中获取唯一值

c++ - 如何在 GCC 中链接 libc 和 libstdc++ 的调试版本?

Java Stream 从对象列表生成映射

list - 将元组列表乘以 F# 中的元组

android - 使用 std::map 时 _Rb_tree_rebalance_for_erase 中的空指针取消引用崩溃