直到几天前,我还认为iterator
的所有与“位置”相关的成员函数都返回了insert()
。我最近发现,虽然erase()
和iterators
函数确实确实会返回begin()
,但end()
和at()
确实会返回{{1} },front()
,back()
不会这样做,它们返回一个简单的引用。
虽然引用使生活变得更轻松,因为我不必取消引用iterator
的拳头,但对我来说,某些成员函数似乎正在返回引用而不是迭代器似乎仍然不一致。如果有的话,C ++会通过提供最低限度的标准来尽量减少这种不一致性,同时仍保持编程的简便性。
答案 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算法的序列,但也有其他用途。