C++ 为什么STL容器可以使用常量迭代器插入
为什么STL容器可以使用C++ 为什么STL容器可以使用常量迭代器插入,c++,stl,iterator,constants,C++,Stl,Iterator,Constants,为什么STL容器可以使用常量迭代器插入?例如,有 iterator std::list::insert (const_iterator position, const value_type& val); 我认为常量迭代器不允许修改容器。它们被称为常量迭代器s,因为它们不允许更改基础值,而不允许更改容器本身。您仍然需要有一个非常量列表来插入元素,因为insert是std::list的非常量成员,但接口是以限制最少的方式创建的 假设您有一个函数,该函数允许您查找某个元素并将其作为迭代器。它
常量迭代器插入?例如,有
iterator std::list::insert (const_iterator position, const value_type& val);
我认为常量迭代器
不允许修改容器。它们被称为常量迭代器
s,因为它们不允许更改基础值,而不允许更改容器本身。您仍然需要有一个非常量列表来插入元素,因为insert
是std::list
的非常量成员,但接口是以限制最少的方式创建的
假设您有一个函数,该函数允许您查找某个元素并将其作为迭代器。它不需要更改任何内容,因此您可以将其设计为返回const\u iterator
。然后您想在这个迭代器中插入到列表
,但是如果列表
的接口比它更受限制,您将无法插入
“我认为常量迭代器不允许修改容器。”
你应该注意到
iterator std::list::insert (const_iterator position, const value_type& val);
// ^^^^^^
实际上是的非常量成员函数。
您仍然需要一个可变的std::list
实例来应用它,容器不会通过迭代器进行修改。position
参数只指定在何处插入新值。除了Spo1ler的答案外,请注意C++11更改了一系列库函数,以精确执行此操作:
[C++11:C.2.12]:
第23条:容器库
23.2.3、23.2.4
更改:签名更改:从迭代器
更改为常量迭代器
参数
理由:规格过高。
效果:以下成员函数的签名从使用迭代器
更改为使用常量迭代器
:
insert(iter,val)
用于向量
,deque
,列表
,集合
,多集
,映射
,多映射
插入(pos,beg,end)
用于向量
,deque
,列表
,转发列表
erase(iter)
用于set
,multiset
,map
,multimap
擦除(开始,结束)
对于设置
,多集
,映射
,多映射
- 所有形式的
列表::拼接
- 所有形式的
list::merge
使用这些函数的有效C++ 2003代码可能无法用这个国际标准编译。
例如:
他们这样做是因为他们最初以为你是这样做的,但后来意识到这毫无意义,无缘无故地让人头痛。这是“过度指定的”
const_迭代器
有助于在范围内迭代时保证元素的不变性,但如果它也意味着您不能使用它来描述容器中执行变异的位置,那么它将是不必要的限制。如果需要这两种行为,则可以始终使容器本身在该范围内保持const
但应注意的是:
map::erase
(以及一些相关方法)在C++03中使用了迭代器,但在C++0x中使用了const_迭代器。当映射的key\u type
具有接受迭代器的构造函数(例如模板构造函数)时,这会中断代码,因为编译器无法在erase(const key\u type&)
和erase(const\u迭代器)
之间进行选择
将元素插入列表时,不会修改其他元素。迭代器仅用于确定插入位置,而不是修改(=调用非常量成员函数)任何现有元素
即使是擦除
也可以使用常量迭代器
。同样,这是因为擦除元素也不会修改它。这听起来很奇怪,但如果你考虑到这一点,那就太微不足道了:
void f()
{
std::string const s = "foo";
// the function ends and s is destroyed even though it was constant
}
我喜欢这个例子。起初我犹豫不决,但实际上这是一个类比。再看一眼,阿尔夫的例子几乎是一样的,即使说得不那么清楚。