Sign in to follow this  

iterators - whats this doing?

This topic is 4075 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, this bit of code seems to work but i want to make sure that i understand what i have done. So here is the code snippet and i will say below what i reckon it is doing.
[source lang = "cpp"]

vector<Student_info> extract_fails_insert(vector<Student_info>& students)
{
	vector<Student_info>::size_type i = 0;
	vector<Student_info>::size_type fails = 0;
	vector<Student_info>::size_type size = students.size();
	vector<Student_info>::iterator iter = students.begin();
	vector<Student_info> passes;

	while (iter != students.end())
	{
		if (fgrade(*iter))
		{
			++fails;
			++iter;
		}
		else
		{
			passes.push_back(*iter);
			++iter;
		}
	}
	
	students.insert(students.begin(), passes.begin(), passes.end());
	students.resize(size - fails);
	cout<<students.size()<<endl;

	return students;
}


Basically i am reckoning that this cycles through the students vector that was passed into it. If it fails it adds to the counter which is at the end used to modify the size of students. If it passes it adds the record to the locally created passes vector and moves onto the next element. Once the end is reached it inserts the contents of the passes vector onto the beginning of the students vector. It then resizes this vector by removing the amount of fails from the original size of the vector. Is this assumption correct. The reason i ask is that it seems to be working fine in my code but i'm not 100 % sure that its correct. Cheers for any help. Neil

Share this post


Link to post
Share on other sites
It will work, but you're doing quite a few things in strangely roundabout ways.

0) I don't really know what to make of that function name.

1) You accept the vector by non-const reference, which means the caller will "see" changes to it. If you intended for this to happen, then there isn't really a need to *also* return the modified vector.

2) Instead of counting fails and subtracting them from the total count, why not just count the passes?

3) In both if-cases, ++iter is done at the end, so you could pull that out of the if condition. Having done that, you can then easily see that what you really want is a for-loop (because you're modifying 'iter' each time through, and then stopping the loop when that same variable reaches a limit).

4) In order to cause 'students' to equal 'passes', you insert 'passes' at the beginning of 'students', determine the size of 'passes', and then cut the result off there (in order to get rid of the original 'students' contents). I can only imagine that you're just doing this sort of thing for practice, because surely it must have just occurred to you to cause 'students' to equal 'passes' by oh, I don't know, *assigning 'passes' to 'students'*? :) You know, as in "students = passes;" Yes, it does work. C++ is designed to let you treat classes as data types that work in the ways you'd expect them to, and the standard library is designed to take advantage of that.

5) The standard library provides algorithms for this anyway so you don't have to write this kind of thing at all. Witness:


#include <algorithm> // in addition to your other includes.

// 'erase' and 'remove_if' come from <algorithm>, and like all the other
// standard library stuff, live in namespace std::.
void remove_failures(vector<Student_info>& students) {
erase(remove_if(students.begin(), students.end(), fgrade), students.end());
cout << students.size() << endl; // although I assume this was for debugging :)
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
#include <algorithm> // in addition to your other includes.

// 'erase' and 'remove_if' comes from <algorithm>, and like all the other
// standard library stuff, live in namespace std::.
void remove_failures(vector<Student_info>& students) {
students.erase(remove_if(students.begin(), students.end(), fgrade), students.end());
cout << students.size() << endl; // although I assume this was for debugging :)
}

Σnigma

Share this post


Link to post
Share on other sites
if i wanted to insert the pass records straight into the start of students, without using a locally created vector how would i do that?.

I did it that way because i have to use the insert function and as far as i am aware that doesn't take indexes in the range fields.

what i really want to do is basically say if its a pass copy to the start of students, if its a fail go to the next one. Then at the end resize the vector to get rid of all the fails using the resize function.

The use of resize and insert are specified by the question in the book i am going through "Accelerated C++".

Share this post


Link to post
Share on other sites

This topic is 4075 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this