尝试在没有显式容器的情况下实现迭代器

Trying to implement an iterator without an explicit container

本文关键字:情况下 实现 迭代器      更新时间:2023-10-16

在我最近的问题之后,我正在尝试实现我自己设计的示例
我有一个基本的结构,但即使读了这篇可能是我见过的最好的教程,我仍然很困惑。我想我可能应该转换这一章_将文本转换为流,并对增量运算符执行类似的操作

string p = "";
string line;
while ( getline(stream, line) ) {
    p += line;
}
return *p;

但我不确定该使用哪种"样板"typedef,以及如何将所有这些东西组合在一起。非常感谢您的帮助

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Paragraph {
public:
  string _text;
  Paragraph (string text) {
    _text = text;
  }
};
class Chapter {
public:
  string _text;
  /*  // I guess here I should do something like:
  class Iterator : public iterator<input_iterator_tag, Paragraph> {
  }
  // OR should I be somehow delegating from istream_iterator ? */
  Chapter (string txt_file) {
    string line;
    ifstream infile(txt_file.c_str());
    if (!infile.is_open()) {
      cout << "Error opening file " << txt_file << endl;
      exit(0);
    }
    while ( getline(infile, line) ) {
      _text += (line + "n");
    }
  }
};
int main(int argc, char** argv) {
  Chapter c(argv[1]);
  // want to do something like:
  // for (<Paragraph>::iterator pIt = c.begin(); pIt != c.end(); pIt++) {
  //    Paragraph p(*pIt);
  //    // Do something interesting with p
  // }
  return 0;
}

由于您没有计划一次加载一章(只是一段),并且您的段落是空的,我认为这可能最好使用单个段落_iterator类

class paragraph_iterator : 
public std::iterator<std::input_iterator_tag, std::string>
{
    std::shared_ptr<std::ifstream> _infile; //current file
    std::string _text; //current paragraph
    paragraph_iterator(const paragraph_iterator &b); //not defined, so no copy
    paragraph_iterator &operator=(const paragraph_iterator &b); //not defined, so no copy
    // don't allow copies, because streams aren't copiable. 
    // make sure to always pass by reference
    // unfortunately, this means no stl algorithms either
public:
    paragraph_iterator(string txt_file) :_infile(txt_file.c_str()) {
        if (!infile.is_open())
            throw std::exception("Error opening file ");
        std::getline(_infile, _text);
    }
    paragraph_iterator() {}
    paragraph_iterator &operator++() {
        std::getline(_infile, _text);
        return *this;
    }
    // normally you'd want operator++(int) as well, but that requires making a copy
    // and std::ifstream isn't copiable.
    bool operator==(const paragraph_iterator &b) const {
        if (_infile.bad() == b._infile.bad())
            return true; //all end() and uninitialized iterators equal
        // so we can use paragraph_iterator() as end()
        return false; //since they all are seperate strings, never equal
    }
    bool operator!=(const paragraph_iterator &b) const {return !operator==(b);}
    const std::string &operator*() const { return _text;}
};
int main() {
    paragraph_iterator iter("myfile.txt");
    while(iter != paragraph_iterator()) {
         // dostuff with *iter
    }
}

流被封装在迭代器中,这样,如果我们对同一个文件有两个迭代器,那么两个都会得到每一行。如果您有一个单独的带有两个迭代器的Chapter类,您可能会遇到"线程化"问题。这是非常简单的代码,而且完全未经测试。我相信有一种方法可以用可复制的迭代器来实现,但要复杂得多。

通常,迭代器类的实现与它所迭代的数据结构密切相关。否则,我们只需要几个通用迭代器类。