[closed]Const iterator zurückgeben oder nicht



  • Hallo hab mal ne Frage und zwar muss/sollte ich in der QueryResult Classe bei den beiden Membern begin und end als Rückgabe cbegin und cend zurückgeben? Im Buch ist das const angegeben aber es werden cbegin und cend zurückgegeben. Aber wenn ich begin jetzt auf einen const QueryResult Objekt aufrufe dann kann ich das ja verändern obwohl das const ist oder nicht? Oder lieber die Member Funktionen überladen oder so was?

    Zeile 37/38:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <memory>
    #include <fstream>
    #include <map>
    #include <set>
    #include <sstream>
    #include <algorithm>
    
    std::string make_plural(int n, std::string main, std::string ex){
    	if(n > 1)
    		return main + ex;
    	else 
    		return main;
    }
    
    class QueryResult; // declaration needed for return type in the query function
    class TextQuery {
    public:
    	using line_no = std::vector<std::string>::size_type;
    	TextQuery(std::ifstream&);
    	QueryResult query(const std::string&) const;
    private:
    	std::shared_ptr<std::vector<std::string>> file; // input file
    	std::map<std::string, std::shared_ptr<std::set<line_no>>> wm;	// map of each word to the set of the lines in which that word appears
    };
    
    class QueryResult {
    	friend std::ostream& print(std::ostream&, const QueryResult&);
    public:
    	using line_no = std::vector<std::string>::size_type;
    	QueryResult(std::string s, 
    				std::shared_ptr<std::set<line_no>> p, 
    				std::shared_ptr<std::vector<std::string>> f)
    			: sought(s), lines(p), file(f) { }
    	inline std::set<line_no>::const_iterator begin() const{return lines->cbegin();}
    	inline std::set<line_no>::const_iterator end() const{return lines->cend();}
    	inline std::shared_ptr<std::vector<std::string>> get_file(){return file;};
    private:
    	std::string sought; // word this query represents
    	std::shared_ptr<std::set<line_no>> lines; // lines it's on
    	std::shared_ptr<std::vector<std::string>> file; // input file
    };
    
    TextQuery::TextQuery(std::ifstream& in) : file(new std::vector<std::string>){
    	std::string line;
    	while(std::getline(in, line)){
    		file->push_back(line);
    		line_no n = file->size() -1;
    		std::istringstream words(line);
    		std::string word;
    		while(words >> word){
    			std::transform(word.begin(), word.end(), word.begin(), tolower);
    			while(true){
    				auto punc = std::remove_if(word.begin(), word.end(), ispunct);
    				if(punc	!= word.end())
    					 word.erase(punc, std::next(punc,1));
    				else
    					break;
    			}
    			auto &setOLines = wm[word];
    			if(!setOLines)
    				setOLines.reset(new std::set<line_no>);
    			setOLines->insert(n);
    		}
    	}
    }
    
    QueryResult	TextQuery::query(const std::string& s) const{
    	static std::shared_ptr<std::set<line_no>> nodata(new std::set<line_no>);
    	std::string lowerS = s;
    	std::transform(lowerS.begin(), lowerS.end(), lowerS.begin(), tolower);
    	auto loc = wm.find(lowerS);
    	if(loc == wm.end())
    		return QueryResult(s, nodata, file);
    	else
    		return QueryResult(s, loc->second, file);
    }
    
    std::ostream &print(std::ostream & os, const QueryResult & qr){
    	os << qr.sought << " was found " << qr.lines->size() << make_plural(qr.lines->size(), " time", "s") << std::endl;
    	for(auto line : *qr.lines)
    		os << "\t(line " << line + 1 << ") "	<< *(qr.file->begin() + line) << std::endl;
    	return os;
    }
    
    void runQueries(std::ifstream &infile)	// infile is an ifstream that is the file we want to query
    {
    	TextQuery tq(infile); // store the file and build the query map
    
    	while (true) {	// iterate with the user: prompt for a word to find and print results
    	std::cout << "enter word to look for, or q to quit: ";
    	std::string s;
    
    	if (!(std::cin >> s) || s == "q") // stop if we hit end-of-file on the input or if a 'q' is entered
    		break;		
    
    	print(std::cout, tq.query(s)) << std::endl;	// run the query and print the results
    	}
    }
    
    int main()
    {
    	std::ifstream in;
    	in.open("text.txt");
    	if(!in)
    		return 0;
    	runQueries(in);
    	return 0;
    }
    

    Ach ja meine Fragestellung ist wahrscheinlich ein bisschen wirr. Also falls ihr was nicht versteht bitte schreiben ich versuch es dann nochmal. Würde mich mal Interessieren wie ihr die Frage stellen würdet.

    EDIT: Hat sich schon selber geklärt 😃


Log in to reply