Custom Iterator for list<class>

Good morning. I have a problem regarding iterators and custom classes. I confess that I am not so confident with them and I am finding difficult to set in mind how to create a custom operator. I know theory but practice is quite different. Can you please show me how could I create a simple custom operator to overload this list<Item> ? Many thanks!

Header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct Item
{
	string name;
	int iid;
	double value;
	friend ostream& operator<<(ostream& os, const Item& ite);
	friend istream& operator>>(istream& is, Item& ite);
	Item();
	Item(string name1, int iid1, double value1);
	~Item() {};
};

list<Item> import_all(list<Item>& l);
void print_all(const list<Item>& v);


Source:
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
#include "stdafx.h"
#include "std_lib_facilities.h"
#include "Header.h"

Item::Item()
	: name{ "" }, iid{ 0 }, value{ 0 } {};
Item::Item(string name1, int iid1, double value1)
	: name{ name1 }, iid{ iid1 }, value{ value1 } {};

ostream& operator<<(ostream& os, const Item& ite)
{
	return os << "String: " << setw(11) << ite.name
		<< "\t" << "IID: " << setw(5) << ite.iid
		<< "\t" << "Value: " << setw(2) << ite.value << endl;
}

istream& operator>>(istream& is, Item& ite)
{
	return is >> ite.name >> ite.iid >> ite.value;
}

list<Item> import_all(list<Item>& l)
{
	cout << "Please input filename: ";
	string iname;
	cin >> iname;

	ifstream ifs{ iname };
	if (!ifs) error("Impossible to open file ", iname);
	while (true)
	{
		Item ite;
		ifs >> ite;
		if (!ifs) break;
		l.push_back(ite);
	}

	return l;
}

void print_all(const list<Item>& l)
{
	for (list<Item>::iterator it = l.begin(); it != l.end(); ++it) // I GOT AN ERROR HERE
	{
		cout << *it << endl;
	}
}
To iterate over a const container you need a const_iterator. You also need to use typename to tell the compiler that const_iterator is actually a type.

1
2
3
4
for (typename list<Item>::const_iterator it = l.begin(); it != l.end(); ++it)
{
	cout << *it << endl;
}


EDIT: You don't need to use typename here because Item is not a template parameter.

Or you could let the compiler deduce the type of the iterator automatically by using the auto keyword.

1
2
3
4
for (auto it = l.begin(); it != l.end(); ++it)
{
	cout << *it << endl;
}


Another possibility is to use range-based for loops and you don't have to have the iterator variable at all.

1
2
3
4
for (const auto& item : l)
{
	cout << item << endl;
}
Last edited on
Okay.. It is actually working.. Thank you Peter87.
Topic archived. No new replies allowed.