在C ++ 14中,const迭代器是否仍然是邪恶的

时间:2014-09-11 09:09:39

标签: c++ iterator c++14

Scott Mayers的“有效STL”第26项标记为“首选iteratorconst_iteratorreverse_iteratorconst reverse iterator”。

原因是某些形式的insert()erase()完全需要iterator,而从其他类型转换是单调且容易出错的。此外,根据STL实施情况,比较iteratorconst_iterator可能会有问题。

该书于2001年发布。第26项中的建议对gcc的当前状态是否仍然有效?

2 个答案:

答案 0 :(得分:18)

C ++ 14标准(N3936)保证iteratorconst_iterator可以自由比较(§23.2.1[container.requirements.general] / p7):

  

在表达式中

i == j
i != j
i < j
i <= j
i >= j
i > j
i - j
     

其中ij表示容器的iterator类型的对象,   其中一个或两个可以被容器的对象替换   const_iterator类型引用相同的元素而没有变化   语义。

此外,容器成员函数从C ++ 11开始接受const_iterator参数(§C.2.13[diff.cpp03.containers] - 可能从标记中推断出来,这是对C的更改) ++ 03):

  

更改:签名更改:从iteratorconst_iterator参数

     

理由:过度指定。 效果:以下成员函数的签名从执行iterator变为了   const_iterator

     
      
  • insert(iter, val)代表vectordequelistsetmultisetmapmultimap
  •   {li> insert(pos, beg, end) vectordequelistforward_list   
  • erase(iter) for集合, {多重集{1}} {地图{1}} multimap`
  •   
  • ,集合, {多重集{1}} {地图{1}} multimap`
  •   
  • 所有形式的erase(begin, end) for
  •   
  • 所有形式的,
  •   

容器需求已经类似地更改为采用const迭代器。此外,通过,成员函数很容易从,获取底层迭代器。因此,问题中提到的问题都不应成为符合标准的编译器中的问题。

答案 1 :(得分:7)

建议已被颠倒过来,正如即将出版的Effective Modern C++的第13项所示,其标题为:

  

首选const_iterators到迭代器

原因是C ++ 11和C ++ 14添加了一些调整,使const_iterators更加实用:

C ++ 11添加

    所有标准库容器的
  • 成员函数cbegin()cend()(以及它们的反向对应项)
  • 使用迭代器识别位置的成员函数(例如insert()erase())现在采用const_iterator代替iterator

C ++ 14通过添加非成员cbegin()cend()(以及他们的反向对应物)来完成