Custom iterator issue

Feb 6, 2017 at 2:02pm
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;
	}
}
Feb 6, 2017 at 2:25pm
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.
Feb 6, 2017 at 3:01pm
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 Feb 6, 2017 at 3:08pm
Feb 6, 2017 at 3:15pm
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.