我们有遗留代码,它返回巨大的原始指针列表到堆分配的对象(我们不能使用智能指针),我们将从列表中删除重复项,并将它们从堆中删除。
现在,正如专家建议的那样,我想尝试 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/