为什么 const_iterator 可以与 std::map::erase 一起使用
Why const_iterator could be used with std::map::erase
我的印象是不能在 const iterator
上使用 erase
。检查 this code.
为什么下面的代码可以编译(C++11,gcc)?
long getMax(const bool get_new)
{
long max_val=0;
TO now=getNow();
map<TO, long>& m=get_new?m_new:m_old;
for(auto it=m.cbegin(); it !=m.cend())
{
if(now.compareTime((*it).first)<lookback)
{
max_val=max(max_val,
(*it).second);
++it;
}
else
{
it=m.erase(it);
}
}
return max_val;
}
map 本身不是常数,但我的理解是 const iterator
应该会导致失败。
行为已从 C++11 改变; std::map::erase 以 const_iterator
作为参数。
void erase( iterator pos ); // (until C++11)
iterator erase( const_iterator pos ); // (since C++11)
iterator erase( iterator pos ); // (since C++17)
对于std::map::erase
,传递的迭代器只是作为删除元素的位置,而不是通过它修改元素。这意味着 const_iterator
就可以了。在C++11之前,对const_iterator
的支持不是很好,但是从C++11开始情况就变了。您现在应该尽可能使用 const_iterator
而不是 iterator
。
位置与其访问的常量无关。进行搜索 return const_iterator
的函数曾经(现在是?)很常见,因为它们实际上根本不更改容器。然而,希望将获得的位置用于序列的突变,例如insert()
相应位置的元素或erase()
定位的元素。因此,扩展容器以支持使用 const_iterator
和变异操作。
相关论文好像是N2350。不知道这篇论文是不是最新版本
我的印象是不能在 const iterator
上使用 erase
。检查 this code.
为什么下面的代码可以编译(C++11,gcc)?
long getMax(const bool get_new)
{
long max_val=0;
TO now=getNow();
map<TO, long>& m=get_new?m_new:m_old;
for(auto it=m.cbegin(); it !=m.cend())
{
if(now.compareTime((*it).first)<lookback)
{
max_val=max(max_val,
(*it).second);
++it;
}
else
{
it=m.erase(it);
}
}
return max_val;
}
map 本身不是常数,但我的理解是 const iterator
应该会导致失败。
行为已从 C++11 改变; std::map::erase 以 const_iterator
作为参数。
void erase( iterator pos ); // (until C++11)
iterator erase( const_iterator pos ); // (since C++11)
iterator erase( iterator pos ); // (since C++17)
对于std::map::erase
,传递的迭代器只是作为删除元素的位置,而不是通过它修改元素。这意味着 const_iterator
就可以了。在C++11之前,对const_iterator
的支持不是很好,但是从C++11开始情况就变了。您现在应该尽可能使用 const_iterator
而不是 iterator
。
位置与其访问的常量无关。进行搜索 return const_iterator
的函数曾经(现在是?)很常见,因为它们实际上根本不更改容器。然而,希望将获得的位置用于序列的突变,例如insert()
相应位置的元素或erase()
定位的元素。因此,扩展容器以支持使用 const_iterator
和变异操作。
相关论文好像是N2350。不知道这篇论文是不是最新版本