C++ 创建自定义end()迭代器
我必须创建类迭代器,在向量中迭代序列以完成任务,但在任务中使用基于范围的循环,如:C++ 创建自定义end()迭代器,c++,iterator,C++,Iterator,我必须创建类迭代器,在向量中迭代序列以完成任务,但在任务中使用基于范围的循环,如: for (T element: sequence) { std::cout << element << " "; std::cin >> numToGenerate; sequence.generateNext(numToGenerate); } for(T元素:序列){ std::不能生成numToGenerate; sequence.generat
for (T element: sequence) {
std::cout << element << " ";
std::cin >> numToGenerate;
sequence.generateNext(numToGenerate);
}
for(T元素:序列){
std::不能生成numToGenerate;
sequence.generateNext(numToGenerate);
}
因此,我应该创建自己的序列和迭代器类来完成任务,但我不知道如何执行end()迭代器
这是我到目前为止的代码:
template<typename T, typename Generator>
class Sequence
{
std::vector<T> elements;
Generator generator;
public:
class Iterator
{
public:
int index;
std::vector<T>& elements;
Iterator(int index, std::vector<T>& elements) : index(index), elements(elements) {};
void operator++()
{
this->index++;
}
T operator*()
{
return this->elements[this->index];
}
bool operator!= ( Iterator other)
{
return this->index != other.index;
}
};
void generateNext(int numToGenerate)
{
for (int i = 0; i < numToGenerate; i++)
{
T next = generator();
elements.push_back(next);
}
}
Iterator begin()
{
return Iterator(0, elements);
}
Iterator end()
{
//??????????
}
};
模板
类序列
{
std::向量元素;
发电机;
公众:
类迭代器
{
公众:
整数指数;
std::向量和元素;
迭代器(int-index,std::vector&elements):索引(index),元素(elements){};
void运算符++()
{
这个->索引++;
}
T算子*()
{
返回此->元素[此->索引];
}
布尔运算符!=(迭代器其他)
{
返回此->索引!=other.index;
}
};
void generateNext(int numToGenerate)
{
对于(int i=0;i
您可以创建指向向量最后一个元素之外的一个位置的结束迭代器,就像“std::vector”迭代器一样
Iterator end()
{
return Iterator(elements.size(), elements);
}
作为替代方案,您可以使用
std::vector::iterator
,并为其创建包装器begin
和end
方法。我不得不说,我觉得您的动机相当可疑。为什么要在迭代元素时将元素推到末尾
您的generateNext
不依赖于索引。不管你是什么索引,你总是在最后推(这意味着你的生成器必须记住它已经生成了哪些元素,即保留一个索引,这不是sequence应该做的吗?)
假设您的循环是书面工作的,则只有在用户多次键入0
直到序列结束时,循环才能结束。将元素插入序列的自然方式是在generateNext
中实现的。我不清楚您为什么要通过迭代序列来干预这一点
无论如何,如果与结束
迭代器进行比较(为了简洁起见,我省略了生成器
),则可以使循环正常工作:
请注意,我特别选择了“生成器”,这样您就可以看到在循环中生成数字的位置。这真的是你想要的吗?让我再问一次:为什么要以这种方式生成sequence?考虑向量是如何填充的:
first iteration: 0 1 2 3 4 105 106 107
^--------------------this one would be printed in your loop
second iteration: 0 1 2 3 4 105 106 107 208 209 210
^
third iteration: 0 1 2 3 4 105 106 107 208 209 210 311 312 313
^
and then some more iterations where we dont add elements to eventually reach the end
底线:我强烈建议您重新考虑您的设计for
循环通常表示您事先知道需要进行多少次迭代。使用迭代器通常有助于独立于容器类型,但在循环中实际上使用的是容器而不是迭代器end
迭代器通常是“脆弱的”,因为如果您推送某个东西,那么即使没有重新分配,以前的end
也不再是了
TL;DR:使用while循环,沿着以下路线:
sequence s;
generator g;
while (g.has_more()) s.push_back(g());
包括
#包括“Sequence.h”
类整数生成器{
int last;
公众:
IntegersGenerator():最后一个(0){}
int运算符()(){
返回此->最后一个++;
}
};
类光纤交流发电机{
int last;
电流;
公众:
FibonacciGenerator():最后(0),当前(0){}
int运算符()(){
如果(此->当前==0&&此->最后==0){
这个->最后一个=1;
返回0;
}
int next=this->last+this->current;
本->上次=本->当前;
本->当前=下一步;
下一步返回;
}
};
模板
void readGenerateWrite(){
序列;
整数生成;
性病::cin>>numToGenerate;
sequence.generateNext(numToGenerate);
for(T元素:序列){
std::不能生成numToGenerate;
sequence.generateNext(numToGenerate);
}
}
int main(){
字符生成器类型;
std::cin>>生成器类型;
如果(generatorType=='i'){
readGenerateWrite();
}
else if(generatorType=='f'){
readGenerateWrite();
}
返回0;
}
这是任务给我的代码,我不能更改。
例如:
输入:
我
3 1 1 0 2 0 0 0
输出:01 2 3 4 5 6本周我被赋予完全相同的任务,你的代码对我帮助很大。您可能已经解决了该任务,但我发现end()返回什么并不重要,它可以与begin()或任何成功编译的内容相同。任务的关键是重载运算符!=所以它在每个循环中得到新的向量大小。我是通过比较变量索引和大小来实现的
bool operator!= ( Iterator other)
{
return this->index != elements.size();
}
这是一个问题,因为序列在Itering时正在更改其大小。如果在迭代时引用插入,如果不缓存end()
的结果,则不会导致任何问题,因为每次调用它都会得到基础向量的更新大小。如果序列在迭代时展开,std::vector
迭代器不起作用:当std::vector
重新分配时,迭代器将失效。这是我的问题。Ad我不知道该做什么,也不清楚为什么要实现自己的迭代器,从这里显示的代码来看,似乎liestd::vector::iterator
已经满足了您的所有需要如果序列在迭代时展开,std::vector iterator将不起作用:当std::vector重新分配时,它将失效。true,虽然你在插入任何地方时都必须小心,但在结尾处除外。请参阅我的答案,以了解更多关于任务的信息,请参阅给我的。
first iteration: 0 1 2 3 4 105 106 107
^--------------------this one would be printed in your loop
second iteration: 0 1 2 3 4 105 106 107 208 209 210
^
third iteration: 0 1 2 3 4 105 106 107 208 209 210 311 312 313
^
and then some more iterations where we dont add elements to eventually reach the end
sequence s;
generator g;
while (g.has_more()) s.push_back(g());
include <iostream>
#include "Sequence.h"
class IntegersGenerator {
int last;
public:
IntegersGenerator() : last(0) {}
int operator()() {
return this->last++;
}
};
class FibonacciGenerator{
int last;
int current;
public:
FibonacciGenerator() : last(0), current(0) {}
int operator()() {
if (this->current == 0 && this->last == 0) {
this->last = 1;
return 0;
}
int next = this->last + this->current;
this->last = this->current;
this->current = next;
return next;
}
};
template<typename T, typename Generator>
void readGenerateWrite() {
Sequence<T, Generator> sequence;
int numToGenerate;
std::cin >> numToGenerate;
sequence.generateNext(numToGenerate);
for (T element : sequence) {
std::cout << element << " ";
std::cin >> numToGenerate;
sequence.generateNext(numToGenerate);
}
}
int main() {
char generatorType;
std::cin >> generatorType;
if (generatorType == 'i') {
readGenerateWrite<int, IntegersGenerator>();
}
else if (generatorType == 'f') {
readGenerateWrite<int, FibonacciGenerator>();
}
return 0;
}
bool operator!= ( Iterator other)
{
return this->index != elements.size();
}