Custom iterator issue

Hello, I'm currently reading up Bjarne Stroustrup, Programming principles and practice using C++ on chapter 20.7.

Visual Studio 2015 won't allow me to compile the following code as I get this error:

error C2794: 'iterator_category': is not a member of any direct or indirect base class of 'std::iterator_traits<_InIt>

Does anyone have an idea why I'm getting this and a possible fix? Thank you

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#pragma once
#include <iostream>
#include<vector>
#include <list>
#include <string>


typedef std::vector<char> Line;

class Text_iterator {
	std::list<Line>::iterator ln;
	Line::iterator pos;
public:
	Text_iterator(std::list<Line>::iterator ll, Line::iterator pp)
		:ln(ll), pos(pp) {}

	char& operator*() { return *pos; }
	Text_iterator& operator++();

	bool operator==(const Text_iterator& other) const
	{
		return ln == other.ln && pos == other.pos;
	}

	bool operator!=(const Text_iterator& other) const
	{
		return !(*this == other);
	}
};

Text_iterator& Text_iterator::operator++()
{
	++pos;
	if (pos == ln->end()) {
		++ln;
		pos = ln->begin();
	}
	return *this;
}
struct Document {
	std::list<Line> line;
	Document() { line.push_back(Line()); }
	
	Text_iterator begin()
	{
		return Text_iterator(line.begin(), line.begin()->begin());
	}
	Text_iterator end()
	{
		std::list<Line>::iterator last = line.end();
		--last;
		return Text_iterator(last, last->end());
	}


};

template<class Iter> void advance(Iter& p, int n)
{
	while (n > 0) { ++p; --n; }
	while (n < 0) { --p; ++n; }
}

std::istream& operator >> (std::istream& is, Document& d) {
	char ch;
	while (is.get(ch)) {
		d.line.back().push_back(ch);
		if (ch == '\n')
			d.line.push_back(Line());
	}
	if (d.line.back().size()) d.line.push_back(Line());
	return is;
}



bool match(Text_iterator first, Text_iterator last, const std::string& s)
{
	std::string ss = s;
	for (std::string::iterator it = ss.begin(); it != ss.end(); ++it)
	{
		if (*first != *it) return false;
		++first;
	}
	return true;
}

Text_iterator find_txt(Text_iterator first, Text_iterator last, const std::string& s)
{
	if (s.size() == 0) return last;
	char first_char = s[0];
	while (true) {
		Text_iterator p = std::find(first, last, first_char);
		if (p == last || match(p, last, s)) return p;
		first = ++p;
	}
}
1
2
#include <iterator> // for std::iterator<>
#include <algorithm> // for std::find etc. 

And then
class Text_iterator : public std::iterator< std::forward_iterator_tag, char > { // ...


Haven't looked at the rest of the code; there may be other things that you have to fix.

For instance, if there is a prefix-increment operator, ideally there should also be a postfix-increment operator.

And in bool match(Text_iterator first, Text_iterator last, const std::string& s)
the return statement at the end should probably be
1
2
// return true;
return first == last ; // true if fully matched 
Note: std::equal() http://en.cppreference.com/w/cpp/algorithm/equal would have done quite nicely here.
Thank you, I'm having trouble understanding some concepts and logic is one of them hence that horrid return in bool match.

The reason for that function I made was for an exercise the book mentioned I want to understand some basic concepts before fully using the STL
Last edited on
If you have reached chapter 20 of Stroustrup's book, having worked through the exercises in the earlier chapters, you are doing quite well.
Topic archived. No new replies allowed.