C++ 拆卸及维修;使用迭代器时在STL中添加元素
我被我正在读的那本书的摘录弄糊涂了C++ 拆卸及维修;使用迭代器时在STL中添加元素,c++,vector,insert,iterator,invalidation,C++,Vector,Insert,Iterator,Invalidation,我被我正在读的那本书的摘录弄糊涂了 我不明白为什么这本书证明对STL使用删除和添加操作是合理的,尽管这会导致迭代器无效。有人能告诉我这本书想要传达的信息吗?在本例中,insert和erase的返回值被分配给iter。这两种方法都会使容器中现有的迭代器无效,但它们返回的迭代器是有效的。作者试图指出的一点是,虽然vector::insert和vector::erase可能会使以前创建的迭代器无效,但它们返回的迭代器必然有效,因此您可以依赖它们 检查此表以准确了解每个STL容器何时发生iter/r
我不明白为什么这本书证明对STL使用删除和添加操作是合理的,尽管这会导致迭代器无效。有人能告诉我这本书想要传达的信息吗?在本例中,
insert
和erase
的返回值被分配给iter
。这两种方法都会使容器中现有的迭代器无效,但它们返回的迭代器是有效的。作者试图指出的一点是,虽然vector::insert
和vector::erase
可能会使以前创建的迭代器无效,但它们返回的迭代器必然有效,因此您可以依赖它们
检查此表以准确了解每个STL容器何时发生iter/ref失效:即使这些操作使(某些)旧的、预先存在的迭代器失效,也不会阻止新创建的迭代器有效。示例程序将无效迭代器的值指定为有效值(文本使用的单词中的“resets”) 这是一个不同但类似的例子:
int* ptr; // an iterator
{
int i;
ptr = &i; // ptr is now valid
} // ptr has become invalid because storage duration of i ended
int j;
ptr = &j; // ptr is valid again despite having been invalid earlier
<> >起首起于C++ 14标准,在成员函数<代码>擦除< /代码>和<代码> INSERT 现在,相应的成员函数(在代码段中使用)声明如下
iterator insert(const_iterator position, const T& x);
iterator erase(const_iterator position);
所以你可以写
auto iter = vi.cbegin();
而不是
auto iter = vi.begin();
并在调用erase
和insert
时使用它
使用成员函数insert
将新元素添加到向量后,向量可以在内部重新分配其元素的内存。在这种情况下,当前迭代器可能无效,因为它将在重新分配之前指向内存
但是该函数返回一个迭代器,该迭代器指向存储在已重新分配的内存中的新插入元素。因此,返回的迭代器将指向内存的实际范围
考虑以下演示程序
#include <iostream>
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v;
v.insert( v.cbegin(), 0 );
std::cout << "v.data() = " << v.data()
<< ", &v[0] = " << &v[0] << '\n';
v.insert( v.cbegin(), 1 );
std::cout << "v.data() = " << v.data()
<< ", &v[0] = " << &v[0]
<< ", &v[1] = " << &v[1] << '\n';
return 0;
}
如你所见,在插入第二个值之后,向量在内存内部重新分配了元素的存储位置。即在插入第二个值之前,函数cbegin
返回的当前迭代器指向地址为0x556699d79e70
的内存范围。插入第二个值后,函数cbegin
返回的当前迭代器将指向地址为0x556699d7aea0
的内存范围。也就是说,前一个当前迭代器无效
但是如果你用下面的方法重写程序
#include <iostream>
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v;
auto iter = v.cbegin();
iter = v.insert( iter, 0 );
std::cout << "v.data() = " << v.data()
<< ", &*iter = " << &*iter << '\n';
iter = v.insert( iter, 1 );
std::cout << "v.data() = " << v.data()
<< ", &*iter = " << &*iter << '\n';
return 0;
}
迭代器iter
始终指向有效的内存范围,因为它是由函数insert返回的迭代器重新分配的,结果指向有效的内存范围
这同样适用于成员函数
erase
。函数迭代器返回的结果无效。From:“不要发布代码、数据、错误消息等的图像-复制或在问题中键入文本”-我看不懂您的图片,但如果要猜,他们使用的事实是erase
将有效迭代器返回到被删除元素之后的元素。这是关于std::set
的,但问题类似。供参考:
#include <iostream>
#include <vector>
#include <iterator>
int main()
{
std::vector<int> v;
auto iter = v.cbegin();
iter = v.insert( iter, 0 );
std::cout << "v.data() = " << v.data()
<< ", &*iter = " << &*iter << '\n';
iter = v.insert( iter, 1 );
std::cout << "v.data() = " << v.data()
<< ", &*iter = " << &*iter << '\n';
return 0;
}
v.data() = 0x55d8c5698e70, &*iter = 0x55d8c5698e70
v.data() = 0x55d8c5699ea0, &*iter = 0x55d8c5699ea0