How to iterate through a list within an object

I am having trouble trying to write a function that takes in an object, and iterates through the list within that object, to print out the list. It is a dictionary type assignment, so it should print out a list of words. I cannot figure out how to access the list.

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
#ifndef LEXICON_H
#define LEXICON_H

#include <iostream>
#include <list>

using namespace std;

class Lexicon {
	
	public:
		
		bool containsWord(const string& word);
		//list<string> startWith(char ch);
		//list<string> startWith(const string& prefix);
		//list<string> endWith(char ch);
		//list<string> endWith(const string& suffix);
		void addWord(const string& str);
		void updateWord(const string& target, const string& replacement);
		
		// Default Constructor
		Lexicon();
		
		// Constructor that takes in words from a file
		Lexicon(const string& fileName);
		
	private:
		list<string> lexicon;
		
	// Overloaded << to print out lexicon
	friend ostream& operator<<(ostream& os, const Lexicon& l);
};

#endif 


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
#include "Lexicon.h"
#include <iostream>
#include <list>

using namespace std;

// Default constructor for empty lexicon
Lexicon::Lexicon() {
	lexicon = list<string>();
}

// Constructor that takes in words from file, and stores them in a lexicon.
// If file does not exist, exception is thrown.
Lexicon::Lexicon(const string& fileName) {
	lexicon = list<string>();
}

// Returns true if word is in dictionary, false otherwise
bool Lexicon::containsWord(const string& word) {
	for(list<string>::iterator it = lexicon.begin(); it != lexicon.end(); it++) {
		if (*it == word) {
			return true;
		}
	}
	return false;
}

// Adds word to lexicon if it is not already there
void Lexicon::addWord(const string& str) {
	for(list<string>::iterator it = lexicon.begin(); it != lexicon.end(); it++) {
		if (*it == str) {
			return;
		}
	}
	lexicon.push_back(str);
}

ostream& operator<<(ostream& os, const Lexicon& l) {
	for (list<string>::iterator it = l.lexicon.begin(); it != l.lexicon.end(); it++) {
		os << *it << endl;
	}
	return os;
}


edit: The rest of the program is not complete, I have been focusing on this so far, so I am aware there are probably issues there as well.
(the overloaded << operator is what is troubling me).
Last edited on
The reference is to a const Lexicon, so use a const_iterator.

1
2
3
4
5
6
7
std::ostream& operator<<( std::ostream& os, const Lexicon& l ) {

	for ( std::list<std::string>::const_iterator it = l.lexicon.begin(); it != l.lexicon.end(); ++it ) {
		os << *it << '\n' ;
	}
	return os;
}


In C++11, we can use auto and let the compiler deduce the type:
http://www.stroustrup.com/C++11FAQ.html#auto
1
2
3
4
5
6
7
std::ostream& operator<<( std::ostream& os, const Lexicon& l ) {

	for ( auto it = l.lexicon.begin(); it != l.lexicon.end(); ++it ) {
		os << *it << '\n' ;
	}
	return os;
}


Or, use a range-based loop:
http://www.stroustrup.com/C++11FAQ.html#for
1
2
3
4
5
6
7
std::ostream& operator<<( std::ostream& os, const Lexicon& l ) {

	for( const auto& str : l.lexicon ) {
		os << str << '\n' ;
	}
	return os;
}
JLBorges, that first bit about the const_iterator makes sense, thank you. It was not explained very well in class, so I am having troubling understanding some of the list functionalities.

However, changing that still does not let me iterate, I am getting an error on
1
2
3
for (list<string>const_iterator it = l.lexicon.begin(); it != l.lexicon.end(); it++ ) {
		os << *it << endl;
}


[Error] conversion from 'std::list<std::basic_string<char> >::const_iterator {aka std::_List_const_iterator<std::basic_string<char> >}' to non-scalar type 'std::list<std::basic_string<char> >::iterator {aka std::_List_iterator<std::basic_string<char> >}' requested
Are you sure your syntax is correct? You are missing the scope resolution operator (::). It should be:
1
2
3
for (list<string>::const_iterator it = l.lexicon.begin(); it != l.lexicon.end(); it++ ) {
		os << *it << endl;
}

#include <string> and place a :: between list<string> and const_iterator.

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
#include <iostream>
#include <string>
#include <list>

// using namespace std; // avoid

class Lexicon {
    
	public:
    
       // ...

        private:
		std::list<std::string> lexicon = { "this", "is", "just", "for", "testing", "the", "overloaded", "operator" } ;
		
	// Overloaded << to print out lexicon
	friend std::ostream& operator<<( std::ostream& os, const Lexicon& l );
};

std::ostream& operator<<( std::ostream& os, const Lexicon& l ) {

    for ( std::list<std::string>::const_iterator it = l.lexicon.begin(); it != l.lexicon.end(); ++it ) {
		os << *it << '\n' 
    }
	return os;
}


int main() {
 
     Lexicon test_lexicon ;
     std::cout << test_lexicon << '\n' ;
}

http://coliru.stacked-crooked.com/a/ff94c4a261e620cb
http://rextester.com/XWMWF53268
I was forgetting the :: in there, whoops.

After adding that and #include <string> it seems to be working. Thank you!
Topic archived. No new replies allowed.