c++ - 更喜欢迭代器而不是指针?

标签 c++ string iterator char-pointer const-pointer

This question 是一个有评论 here 但作为问题的一部分被删除的问题。

对于那些看不到已删除帖子的人,评论是关于我在 this answer 中使用 const char* 而不是 string::const_iterator: “从一开始,迭代器可能是一条更好的路径,因为它似乎正是处理指针的方式。”

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

最佳答案

简介

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

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


调试

由于除其他事项外,取消引用传递到范围末尾的迭代器是未定义的行为,因此在这种情况下,实现可以自由地做任何它认为必要的事情——包括引发诊断说你做错了什么。

标准库实现,libstdc++ ,由 gcc 提供,当它检测到某些故障时会发出诊断(如果启用了 Debug Mode)。


示例

#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;
}
/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

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

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



(可能)更好的类型安全

由于迭代器的实际类型是实现定义的,这可以用来提高类型安全性——但您必须检查您的实现文档以看看是不是这样。


考虑下面的例子:

#include <vector>

struct A     { };
struct B : A { };

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

void ptr_func (B * beg, A * end);
                     // ^-- oops

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)
}

阐述

  • (A) 根据实现的不同,可能是一个编译时错误,因为 std::vector<A>::iteratorstd::vector<B>::iterator可能不是同一类型。
  • 但是,
  • (B) 总是会编译,因为存在从 B* 的隐式转换。至 A* .

关于c++ - 更喜欢迭代器而不是指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29099139/

相关文章:

c++ - 在多个键下将项目存储在 map 中

python - 在文本 block 中添加换行,但不要打断单词

c++ - 延迟特定时间的方法调用

c++ - 如何使用 Visual Studio 2008 构建在普通旧 XP SP2 上运行且没有并排 DLL 的 C++ 应用程序?

c++ - 如何对模板类中的不同模板参数执行不同的操作?

python - 读取数据时删除列包含某些字符串: python

c++ - 将整个 ASCII 文件读入 C++ std::string

c++ - 如果 "key"不存在,map::find() 会返回什么样的值?

c++ - std::iterator、指针和 VC++ 警告 C4996

c# - 使用枚举器在数组中显示结构