我正在用C ++学习迭代器。作者提到迭代器可以是正常的指针,但在某些情况下它们可能是不同的。
作者究竟是什么意思?智能指针?
答案 0 :(得分:1)
作者意味着迭代器可以实现为自定义(在某些情况下非常复杂)的对象。他们不必成为指针。相反,他们认为表现就像他们一样(至少在某种程度上)。
以下是迭代器的非常基本示例,它并没有真正做到很多。这是一个input-iterator-category实现,只是迭代一系列数字。关键是它显然是一个迭代器实现,但很明显没有与指针有关。
我已经冒昧地用调试输出加载它,这样你就可以看到发生了什么。它提供传统和基于范围的迭代示例。两者的产出差异......有趣:
#include <iostream>
#include <iterator>
struct Range
{
Range(int low, int high)
: low(std::min(low,high))
, high(std::max(low,high))
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
// custom iterator for our Range type
struct iterator : public std::iterator<std::input_iterator_tag, int, std::ptrdiff_t, int*, int>
{
friend struct Range;
iterator& operator ++()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
++myvalue;
return *this;
}
iterator operator ++(int)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return iterator(range, myvalue++);
}
int operator*() const
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return myvalue;
}
bool operator ==(const iterator& it) const
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return myvalue == it.myvalue;
}
bool operator !=(const iterator& it) const
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return myvalue != it.myvalue;
}
private:
iterator(Range& range, int value)
: range(range)
, myvalue(value)
{
std::cout << __PRETTY_FUNCTION__ << '\n';
}
Range& range;
int myvalue;
};
iterator begin()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return iterator(*this, low);
}
iterator end()
{
std::cout << __PRETTY_FUNCTION__ << '\n';
return iterator(*this, high+1);
}
private:
int low, high;
};
int main()
{
Range range(1,5);
// traditional iteration
for (Range::iterator it = range.begin(); it != range.end(); ++it)
std::cout << *it << '\n';
std::cout << '\n';
// C++11 range-based iterator
for (auto n : range)
std::cout << n << '\n';
std::cout << '\n';
}
<强>输出强>
Range::Range(int, int)
Range::iterator Range::begin()
Range::iterator::iterator(Range &, int)
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
1
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
2
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
3
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
4
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
5
Range::iterator &Range::iterator::operator++()
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
Range::iterator Range::begin()
Range::iterator::iterator(Range &, int)
Range::iterator Range::end()
Range::iterator::iterator(Range &, int)
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
1
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
2
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
3
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
4
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
int Range::iterator::operator*() const
5
Range::iterator &Range::iterator::operator++()
bool Range::iterator::operator!=(const Range::iterator &) const
我知道这很简单,但关键是要证明迭代器不必是指针,甚至使用指针。他们如何迭代他们正在迭代的任何内容最终将由迭代器实现本身决定,只要它符合它声称支持的迭代器类别的要求。
希望有所帮助。
答案 1 :(得分:0)
指针是实现迭代器的一种方法。标准允许这样做,但它也允许其他实现,例如持有引用的对象。唯一重要的是为其声明的迭代器类别提供正确的公共接口。
由于指针有operator++
,operator*
以及其他指针,因此它们可以充当std::vector
和std::array
等连续集合的迭代器。
但是,它们不能充当链表的迭代器,因为operator++
没有正确的语义。
答案 2 :(得分:0)
迭代器有不同的类别(分类):
正常指针位于随机访问分类下。这意味着它具有随机访问的属性。
指针可以递增和递减。主要区别在于增量和减量的定义。递增的存储器位置方程是:
Next_Location = Previous_Location + sizeof(Target_Data_Type);
内存位置取决于指针指向的数据类型。
从 Forward_Iterator 派生的迭代器将指向下一项;不一定到下一个内存位置。一个例子是链表。链表中的 next 项可以在内存中的任何位置;不一定是下一个记忆位置。
所以一个重要的区别是递增一个interator使它指向下一个项并且递增一个指针使它指向下一个内存位置(调整数据类型的大小)< /强>