为什么向量的.at()成员函数返回引用而不是迭代器?

时间:2018-07-18 10:49:28

标签: c++ stl

直到几天前,我还认为iterator的所有与“位置”相关的成员函数都返回了insert()。我最近发现,虽然erase()iterators函数确实确实会返回begin(),但end()at()确实会返回{{1} },front()back()不会这样做,它们返回一个简单的引用。

虽然引用使生活变得更轻松,因为我不必取消引用iterator的拳头,但对我来说,某些成员函数似乎正在返回引用而不是迭代器似乎仍然不一致。如果有的话,C ++会通过提供最低限度的标准来尽量减少这种不一致性,同时仍保持编程的简便性。

3 个答案:

答案 0 :(得分:9)

at方法来自称为“元素访问”的常见容器方法,这些方法返回引用,指针。 还有另一组称为“迭代器”的通用容器方法,这些方法返回迭代器。 对于标准库,这是一个清晰,简单且众所周知的设计决策。

元素访问

  • at:通过边界检查访问指定的元素
  • operator[]:访问指定的元素
  • front:访问第一个元素
  • back:访问最后一个元素
  • data直接访问基础数组

迭代器

  • begin / cbegin将迭代器返回到开头
  • end / cend将迭代器返回末尾
  • rbegin / crbegin将反向迭代器返回到开头
  • rend / crend将反向迭代器返回末尾

在迭代器概念中,可通过STD的std::advance方法访问迭代器范围内的元素。这当然适用于InputIterator,BST,列表,向量等,当然它们具有不同的复杂性。

答案 1 :(得分:1)

begin()end()insert()erase()等是对向量的元素序列本身起作用的方法,而operator [],{ {1}},at()front()是访问此序列的具体元素的方法。我在这里看不到任何不一致之处。它们存在于所有序列容器中,并且在概念上总是做相同的事情。当然,您可以自己实现back()front()之类的东西,没有什么可以阻止您这样做。根据定义,它们分别等于分别取消引用back()begin()。它们的存在是为了方便。根据您想走多远,prev(end())本身的存在只是为了方便……

答案 2 :(得分:0)

标准模板库呈现的抽象是序列迭代器算法。容器是创建和管理序列的一种方法,但不是唯一的方法。例如,通过创建std::istream_iterator,可以将输入流用作序列。但是,如果int i; double d; std::cin >> i >> d;定义了基于迭代器的接口,则类似std::cin这样的事情将很难编写。容器也是一样:它们在迭代以外的环境中很有用,并且它们定义了适合其一般用途的接口;这些用途之一是作为STL算法的序列,但也有其他用途。