倾向于过度指针的迭代器?

Jon*_*Mee 3 c++ string iterator char-pointer const-pointer

这个问题是一个问题的一个问题,在这里有一个评论但被删除作为碰撞的一部分.

对于那些看不到删除的帖子的人来说,评论是关于我在这个答案中使用const char*s而不是string::const_iterators :"迭代器可能是一个更好的路径,因为它似乎正是你的指针似乎被处理."

所以我的问题是,迭代器是否持有string::const_iterators的任何内在价值,const char*以便将我的答案转换为string::const_iterators有意义?

Fil*_*efp 6

介绍

使用迭代器而不是指针有很多好处,其中包括:

  • 发布与调试中的不同代码路径,以及;
  • 更好的类型安全性;
  • 使得编写通用代码成为可能(迭代器可以用于任何数据结构,例如链表,而内部指针在这方面非常有限).


调试

除其他事项外,解除引用传递范围末尾的迭代器是未定义的行为,在这种情况下,实现可以自由地执行任何必要的操作 - 包括提出诊断,说明你做错了什么.

gcc提供的标准库实现libstdc ++将在检测到故障时发出诊断信息(如果启用了调试模式).


例

#define _GLIBCXX_DEBUG 1 /* enable debug mode */

#include <vector>
#include <iostream>

int
main (int argc, char *argv[])
{
  std::vector<int> v1 {1,2,3};

  for (auto it = v1.begin (); ; ++it)
    std::cout << *it;
}
Run Code Online (Sandbox Code Playgroud)
/usr/include/c++/4.9.2/debug/safe_iterator.h:261:error: attempt to 
    dereference a past-the-end iterator.

Objects involved in the operation:
iterator "this" @ 0x0x7fff828696e0 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPiNSt9__cxx19986vectorIiSaIiEEEEENSt7__debug6vectorIiS6_EEEE (mutable iterator);
  state = past-the-end;
  references sequence with type `NSt7__debug6vectorIiSaIiEEE' @ 0x0x7fff82869710
}
123
Run Code Online (Sandbox Code Playgroud)

如果我们使用指针,无论我们是否处于调试模式,上述情况都不会发生.

如果我们不为libstdc ++启用调试模式,将使用更加性能友好的版本(没有添加簿记)实现 - 并且不会发出诊断.



(可能)更好的类型安全

由于迭代器的实际类型是实现定义的,因此可以用于提高类型安全性 - 但是您必须检查实现的文档以查看是否是这种情况.


考虑以下示例:

#include <vector>
Run Code Online (Sandbox Code Playgroud)

struct A     { };
struct B : A { };
Run Code Online (Sandbox Code Playgroud)

                                                      // .-- oops
                                                      // v
void  it_func (std::vector<B>::iterator beg, std::vector<A>::iterator end);

void ptr_func (B * beg, A * end);
                     // ^-- oops
Run Code Online (Sandbox Code Playgroud)

int
main (int argc, char *argv[])
{
  std::vector<B> v1;

   it_func (v1.begin (), v1.end  ());               // (A)
  ptr_func (v1.data  (), v1.data () + v1.size ());  // (B)
}
Run Code Online (Sandbox Code Playgroud)

精

  • (A)可以,取决于实现,是因为编译时误差std::vector<A>::iterator并且std::vector<B>::iterator可能是同一类型的不.
  • 然而,(B)总是会编译,因为从而隐式转换B*为A*.