在删除之前更新一组元素指针中的元素
Update element in a set of pointer of elements before deletion
我有一些在unordered_map中分配的类实例。我也有不同的容器,用于存储指向这些元素的指针,这些元素具有不同的顺序。这意味着,例如,我有一个 std::set 指向映射中分配的元素的指针,按实例字段的子集排序。
由于我可以访问实数元素,因此我可以更改它们的字段,但我知道我不应该在集合排序中使用的字段上执行此操作。实际上,在更改这些字段之前,我需要做的是从集合中删除对象的指针,更改这些字段并再次插入,如下所示:
set<Element*, Comparator> s; // Elements ordered by field_2
s.erase(element);
element->field_2 = 4;
s.insert(element);
但是,维护不同排序的其他容器是由我自己实现的,我知道我可以更改这些值,然后通知容器字段已更新。所以我想知道我是否可以将这些指令的顺序更改为这个:
element->field_2 = 4;
s.erase(element);
s.insert(element);
我想这样做的原因是我希望所有这些容器共享相同的接口。所以理想情况下,我想更改字段,然后调用容器的方法 container.value_updated(元素(。
那么,我可以修改关键field_2然后立即调用删除和插入吗?还是删除会失败,因为field_2的值可能不一致?(我认为这将取决于实现,但我想确保(
用作std::set
键的数据不得更改。否则,std::set
的顺序将被破坏,并且无法再对std::set
中的元素进行寻址。
出于好奇,我试图以错误的方式做这件事。
虽然我知道这是未定义的行为,但我运行了这个 - 一个很好的证明坏事发生了:
#include <iostream>
#include <set>
#include <vector>
typedef int Entry;
struct Less {
bool operator()(const Entry *p1, const Entry *p2) const
{
return *p1 < *p2;
}
};
int main()
{
const int N = 10;
std::vector<int> data;
for (int i = 0; i < N; ++i) data.push_back(i);
std::set<Entry*, Less> set;
for (int &value : data) set.insert(&value);
// do it wrong
data[2] = 12;
set.erase(&data[2]);
set.insert(&data[2]);
// check result
for (const Entry *pValue : set) std::cout << ' ' << *pValue;
std::cout << 'n';
// done
return 0;
}
输出:
0 1 12 3 4 5 6 7 8 9 12
科里鲁的现场演示
那么,我可以修改关键
field_2
然后立即调用删除和插入吗?
不。这有可能破坏集合中指针的顺序。
或者删除会失败,因为
field_2
的值可能不一致?
这是一个明显的可能性。但是,此时,您正在查看未定义的行为。无法预测会发生什么。
(我认为这将取决于实现,但我想确保(
未定义的行为部分不依赖于实现。
- 在 c++ 中拥有一组结构的正确方法是什么?
- 如何根据对的第二个元素对 STL c++ 中的一组对进行排序?
- 如何通过查找迭代器结果分配给一组对的元素
- 在删除之前更新一组元素指针中的元素
- 无法在STL中打印一组矢量的元素
- 迭代一组和擦除元素
- 最长的子序列,其元素构成一组递增的整数
- 如何查找一组类型对是否包含一个元素作为第二个成员
- 如何访问一组对元素的图
- 如何在对一组中的一对之间找到一个元素
- 如何创建一组UI元素,您可以迭代
- 一组结构缺少元素
- 基于权重在N个桶之间分配一组元素
- 对于一组不断添加和删除的元素,我应该使用哪个容器
- 查找一组元素的位置
- 通过索引删除一组元素
- 更改一组数据结构中元素的值
- 运算符重载,用于创建一组类型为 pair<int、int> 的元素
- 从一组集合{{中选择一组数字{1,2,3}.},{.},{.}}使得所有元素都是唯一的
- 将一组元素分解成最少数量的回文