请注意,此代码不是我写的。否则我不会问这个问题。完全归功于Jerry Coffin。无论如何,代码通过重载std :: iterator<生成一系列数字。 >
我将首先发布代码,然后我会解释我所看到的内容。如果一个专家C ++成员可以纠正我,如果我错了,我会非常感激。
代码
static const int N = 10;
template <class T>
class sequence : public std::iterator<std::forward_iterator_tag, T>
{
private:
T val;
public:
sequence(T init) : val(init) { }
T operator *( ) { return val; }
sequence &operator++( ) { ++val; return *this; }
bool operator != ( const sequence &other ) { return val != other.val; }
};
void foo( )
{
typedef std::vector<int> graph;
graph id1( gen_seq(0), gen_seq( N ) );
display( id1 ); /* Not declared */
}
/* displays: 0 1 2 3 4 5 6 7 8 9 */
所以当看到这个时,我看到你创建了一个包含值的类。现在我们将其中两个传递给vector的构造函数,它可以使用两个迭代器。现在每次向量的构造函数在“序列”上使用++运算符时,它会递增迭代器内部的值。从技术上讲,你可以写:
graph id1( gen_seq( 0 ), gen_seq( 0 ) );
这会生成相同的序列吗?或者是!=运算符检查以确保0没有进入N.任何输入都会有很大帮助。我刚刚阅读了Stroustrup的C ++编程语言第3版,在那里他谈到了迭代器,但是继承它们并不是一个很大的话题,而我还没有完全理解。好吧,我会做他所有的练习,因为我记得他要求多次重载迭代器。
答案 0 :(得分:5)
你真的没有重载迭代器;你正在编写自己的迭代器,这涉及到一些运算符的重载。
std::vector
构造函数实际上看起来像这样:
template <typename ForwardIterator>
vector(ForwardIterator first, ForwardIterator last)
{
for (ForwardIterator it = first; it != last; ++it)
push_back(*it);
}
(实际上,它比这更复杂,因为它需要更有效地处理随机可访问范围,但对于前向可迭代范围,这就是它的作用。)
如您所见,该构造函数对您的迭代器执行三个操作:它取消引用它(*it
),它递增它(++it
),并执行不等式比较({{1} })。它执行上述每个操作的位置,它会调用您在自定义迭代器类中定义的相应运算符。
it != last
会起作用,但不会产生相同的结果:它会使graph id1( gen_seq( 0 ), gen_seq( 0 ) );
为空。根据前几段的解释,你明白为什么吗?
答案 1 :(得分:3)
否graph id1( gen_seq( 0 ), gen_seq( 0 ) );
将生成零大小的矢量。使用!=
的第二个解释更接近。如果你理解了矢量ctor代码,可能会有所帮助。它是这样的
template <class II>
vector::vector(II first, II last)
{
while (first != last)
{
push_back(*first);
++first;
}
}
如您所见,!=
用于确定何时停止向向量添加项目。
(由于各种技术和效率原因,实际的矢量ctor代码可能比这复杂得多,但上面给出了适用于你的情况的本质)。