std::iterator::reference and ::pointer

Hi, I am kind of confused that when I'm using std::iterator as base class for my reverse_iterator I cant use name aliases that I'm inheriting from this base in my reverse_iterator
It worked on Visual Studio but didn't work when I compiled it in cpp.sh
Here is the code (look for commented part)

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
#include <iostream>
#include <iterator>
#include <vector>

template<typename T>
using Iterator_category = typename std::iterator_traits<T>::iterator_category;

template<typename T>
using Value_type = typename std::iterator_traits<T>::value_type;

template<typename T>
using Difference_type = typename std::iterator_traits<T>::difference_type;

template<typename T>
using Pointer = typename std::iterator_traits<T>::pointer;

template<typename T>
using Reference = typename std::iterator_traits<T>::reference;


template<typename Iter>
class reverse_iterator : public std::iterator<Iterator_category<Iter>,
                                              Value_type<Iter>,
					      Difference_type<Iter>,
					      Pointer<Iter>,
					      Reference<Iter>>
{
public:
	using iterator_type = Iter;

	reverse_iterator() : current{} {}
	explicit reverse_iterator(Iter p) : current{ p } {}

	template<typename Iter2>
	reverse_iterator(const reverse_iterator<Iter2>& p) : current{ p.base() } {}


	Iter base() const { return current; }

//  THIS WORKS
	Reference<Iter> operator*() { tmp = current; return *(--tmp); }
	Pointer<Iter> operator->() { tmp = current; return &*--tmp; }

//  THIS DIDN'T WORK
//	reference operator*() { tmp = current; return *(--tmp); }
//	pointer operator->() { tmp = current; return &*--tmp; }  


protected:
	Iter current;
private:
	Iter tmp;
};



int main()
{
	std::vector<int> vec{ 1,2,3,4,5,6,7,8,9 };
	reverse_iterator<typename std::vector<int>::iterator> iter{ vec.end() };

	std::cout << *iter << std::endl;

	system("pause");
}


Why is plain reference and pointer is not working as return types?
Last edited on
Hey, this was very important question for me and I got an answer to it on cprogramming forum and I just want to share the answer jsut in case someone ever needs it.

It was answered by kmdv.

You need to specify type with the typename keyword. The reason is that your reverse_iterator is a class template and, what is really important here, its base class depends on a template argument - Iter. This means that when the compiler sees your type definition, it does not know what std::iterator<...> exactly is, because what it is depends on Iter (which is unknown). If you really want to refer to reference, pointer, and other members from std::iterator<...>, you need to qualify it:
typename std::iterator<VERY LONG ARGUMENT LIST>::reference METHOD();
To avoid repeating this extremely long argument list, it would be convenient to add a typedef to the base class before:
1
2
3
4
5
6
7
8
9
10
11
12
13
template <class Iter>
class reverse_iterator<Iter> : public std::iterator<VERY LONG ARGUMENT LIST>
{
private:
    typedef std::iterator<VERY LONG ARGUMENT LIST> base_type;
 
public:
    using typename base_type::reference;
    using typename base_type::pointer;
 
public:
    reference METHOD();
};

However, do you really need your own reverse iterator? Just in case you don't know, there is already a reverse iterator adaptor in STL: std::reverse_iterator<Iter>.


Link :
http://cboard.cprogramming.com/cplusplus-programming/169761-std-iterator-pointer-std-iterator-reference.html
Topic archived. No new replies allowed.