Stl::map erase与std::vector erase的行为不同
stl::map erase vs std::vector erase behave differently
class CSensor
{
public:
CSensor(int nVal1,char* pVal2,unsigned int nVal3);
CSensor(const CSensor& refMessage);
const CSensor& operator=(const CSensor& refMessage);
~CSensor(void);
private:
int m_nVal1;
char* m_pVal2;
unsigned int m_nVal3;
};
// vector erase
std::vector<CSensor> SensorList;
CSensor obj1(1,"Test1",10);
SensorList.push_back(obj1);
CSensor obj2(2,"Test2",11);
SensorList.push_back(obj2);
CSensor obj3(3,"Test3",12);
SensorList.push_back(obj3);
SensorList.erase (SensorList.begin()+1);
// map erase
std::map<int ,CSensor> ListSensor;
CSensor obj11(1,"Test1",10);
CSensor obj12(2,"Test2",11);
CSensor obj13(3,"Test3",12);
ListSensor.insert(std::pair<int,CSensor>(1,obj11));
ListSensor.insert(std::pair<int,CSensor>(2,obj12));
ListSensor.insert(std::pair<int,CSensor>(3,obj13));
ListSensor.erase(2);
我调试了两种情况。在这两种情况下,我都在删除第二个元素。如果是矢量它将第3个元素复制到第二个位置,然后删除第3个位置。
所以当你输入
List.erase (List.begin()+1);
调用赋值操作符(CSensor=),然后调用析构函数。
在map的情况下,当我做
ListSensor.erase(2);
只调用析构函数
我已经通过STL矢量vs映射擦除。它说迭代器,无法解释行为。
我的问题是为什么擦除行为不同的这两个STL容器??
这不是.erase
本身的行为,而是每个容器各自工作方式的结果。
从向量中删除
当你从vector (List
是一个真的不适合vector的名字,btw)中删除时,它的内容必须被洗牌以填补空白,因为vector的元素总是连续地存储在内存中。
这通常是通过复制(或移动)元素,然后删除剩余的元素来完成的:
-
内存中的Vector元素:
+---+---+---+---+---+---+---+---+---+ | a | b | c | d | e | f | g | h | i | +---+---+---+---+---+---+---+---+---+
-
删除"e":
+---+---+---+---+---+---+---+---+---+ | a | b | c | d | | f | g | h | i | +---+---+---+---+---+---+---+---+---+
-
通过复制/移动来填充空白:
<-- +---+---+---+---+---+---+---+---+---+ | a | b | c | d | f | f | g | h | i | +---+---+---+---+---+---+---+---+---+ <-- +---+---+---+---+---+---+---+---+---+ | a | b | c | d | f | g | g | h | i | +---+---+---+---+---+---+---+---+---+ <-- +---+---+---+---+---+---+---+---+---+ | a | b | c | d | f | g | h | h | i | +---+---+---+---+---+---+---+---+---+ <-- +---+---+---+---+---+---+---+---+---+ | a | b | c | d | f | g | h | i | i | +---+---+---+---+---+---+---+---+---+
-
调整容器大小:
+---+---+---+---+---+---+---+---+ | a | b | c | d | f | g | h | i | +---+---+---+---+---+---+---+---+
从映射中删除
对于map来说不是这样,它的内容不一定连续存储在内存中(实际上,复杂性要求意味着它几乎总是一个充满指向不连续数据的指针的树结构)。
这是使用不同容器的原因之一!
vector必须复制被删除元素后面的元素,以覆盖它留下的"洞"。否则这些元素将不再是连续的。
map将元素保存在树结构中,只需要调整一些指针来重新平衡树。
为vector辩护:复制一对元素可能比单独分配树节点并保持树平衡更便宜。总是有权衡的!
相关文章:
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- std::multimap::erase() 在迭代时
- 为什么 std::erase(std::erase_if) 不是适用于<algorithm>任何容器的模板?
- 为什么"std::set::erase(const key_type&)"返回"size_type"而不是"bool"?
- std::vector::erase() 真的会在擦除时使迭代器失效吗?
- 为什么 std::set::erase 与 std::set::insert 不一致?
- 新的 std::map::erase() 签名 C++17.
- 如何为向量实现 std::erase ?
- C++代码"x.erase(std::remove(x.begin(), x.end(), ), x.end())"是如何工作的?
- std::vector::erase 的 MoveAssignable 要求与 std::vector::emplace_back 的 MoveInsertable 要求
- 没有 std::string .erase() 的重载函数实例
- 使用std::vector中的函数erase
- 为什么 std::vector 迭代器在 erase() 调用后失效?
- std :: vector :: erase(item)需要为项目定义的分配操作员
- 使用 std::unique 和 vector.erase 删除除最后一次出现的重复元素之外的所有元素
- std::map::erase()-重载速度更快
- std::string::erase() 的定义行为是什么,带有 string::npos
- Lint更喜欢在std:string上使用erase()方法,而不是clear()方法
- 为什么std::whatever::erase()是一个方法,std::remove()是独立函数
- std::erase 和 std::remove 组合以删除特定元素不适用于特定示例