Is this the 'most vexing parse'?

I get this error:
"Error: expression must have class type"

when I try to execute this line:
aList.push_back(myString.substr( current, next - current ));

I am trying to write a function that takes in a string and, using a space as a delimiter, extracts each word and stores it in a list. Then the function returns a pointer to that list to be used in my larger program.

What is confusing is that EVERYTHING seems to work just fine when I don't have to call a method of aList. For instance,
cout << myString.substr( current, next - current ) << endl;

in the context of my program prints out everything that I need exactly the way it should and all of my special cases in my code seem to catch everything correctly.

Here is the code if it helps:

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
int main()
{
	list<list<string>> masterList;

	ifstream inData;
	string fileName, line;
	cout << "Enter input filename containing a list of phrases, one line per phrase\n> ";
	cin >> fileName;
	cout << endl;

	inData.open(fileName);

	while ( inData.good() ) 
	{
		getline (inData, line); //read in a line of the data file using getline. 

		//check for empty or all spaces
                if (line.length() != 0 && (is_all_spaces(line) == false)) 
			masterList.push_back(*function(line)); //add the returned list to masterList
	}

	inData.close();

	return 0;
}

	//Receives a line of the data file to parse into individual words. 
	//Will store each word in a list and return a pointer to the list.
list<string>* function(string myString) 
{
	list<string> *aList = new list<string>; 

	myString.length();
	string delimiter = " ";
	int current = 0; 

	while (myString[current] == ' ')
		++current;

	int next = current - 1; 


	do
	{
		while (myString[current] == ' ')
			++current;
		next = current - 1;

		current = next + 1;
		next = myString.find_first_of( delimiter, current ); 
		aList.push_back(myString.substr( current, next - current )); 
		current = myString.find_first_of( delimiter, current );
	}
	while (next != string::npos); //do while not at end of the string

	return aList; //pass back the pointer to the new list object
}

	//checks if a string is made up entirely of white spaces (a special case)
bool is_all_spaces(string line)
{
	int i = 0;
	int len = line.length();

	if (len != 0)
	{
		while (i < len)
		{
			if (line[i] != ' ')
				return false;
			else
				++i;
		}
		return true;
	}
	return true;
}


Also, for future reference, would this question have done better in this Beginner Forum or the General C++ Programming forum?
Last edited on
You declared aList as a pointer to an std::list<string>. Either use the '->' operator to access members, or declare it as a regular list.
I think I was trying originally to push a string value onto the pointer itself (aList is a pointer) rather than the list it pointed to. This seems to have fixed it:

aList->push_back(myString.substr( current, next - current ));

If you're going to return memory that's new'd you need to keep track of and delete that memory at some point, but there isn't really any reason to use new here. As it is you leak memory every time you call function.

Btw, you can simplify function greatly by using a stringstream.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <sstream>


typedef std::list<std::string> list_type ;

	//Receives a line of the data file to parse into individual words. 
	//Will store each word in a list and return a pointer to the list.
list_type function(const std::string& myString) 
{
	list_type aList ;

	std::istringstream words(myString) ;
	std::string word ;

	while ( words >> word )
		aList.push_back(word) ;

	return aList ;
}


Last edited on
Topic archived. No new replies allowed.