Sign in to follow this  
ArchG

C++ and Vector/Iterator Question

Recommended Posts

Hey, sorry for the really noobish question, but I have an vector of a custom struct, and i'm trying to iterate through it, and change elements, is this possible?
void update_word( int id, vector<CustomStruct> &v)
{	
	//create iterator to loop through the vector
	vector< CustomStruct >::iterator i;
	
        //check every element in the vector starting at the beginning
	for (i = v.begin(); i != v.end(); i++)
	{
	       //get the WordStat struct
		CustomStruct cs= *i;
		//check to see if it's the same id
		if (cs.id == id)
		{
			cs.count++;
		}
        }
}

That's kinda what i'm trying to do..but obviously the problem is .. cs.count++ doesn't do anything, because i'm modifying a copy, and not the real thing. What do I do to modify the contents of the real thing? (I realize other containers would be better suited for this, but I want to do it with a vector for other reasons) Thanks, ArchG

Share this post


Link to post
Share on other sites
my two pennies:


void update_word( int id, vector<CustomStruct> &v)
{
//check every element in the vector starting at the beginning
for (int i = 0; i < v.size(); i++)
{
//check to see if it's the same id
if (v[i].id == id)
{
v[i].count++;
}
}
}

Share this post


Link to post
Share on other sites
the "i" retruns a renfernce to the object in the vector.
When you used "CustomStruct cs= *i;" you created a copy in "cs"
When using "cs.count++;" you were updating the copy and not the orginal

Share this post


Link to post
Share on other sites
Quote:
Original post by SillyCow
the "i" retruns a renfernce to the object in the vector.
When you used "CustomStruct cs= *i;" you created a copy in "cs"
When using "cs.count++;" you were updating the copy and not the orginal


OP understood that and is looking for a work around.

Quote:
Original post by rlyeh_


Ugh, no. That's taking a step backwards.

Quote:
Original post by swecoder
try change to

if ((*i).id == id)
{
(*i).count++;
}


That would work, but is missing the point. Also, (*x).y, in generally, is more idiomatically written as x->y.

Quote:
Original post by Sc4Freak
Use a reference.

CustomStruct& cs = *i;


We have a winner. This is a useful technique in general (although if you're using it to wrap up a chain of member access, it's a sign that the object is missing some member functionality).

But here's something else to consider:


#include <algorithm> // etc.

void update_word(int id, vector<CustomStruct>& v) {
// The anonymous structure lets us define a kind of function which
// can have one of its arguments (the id) "bound":
struct {
int id;
void operator()(CustomStruct& cs) {
if (cs.id == id) {
cs.count++;
}
}
} updater = { id };

// And then we use a standard library algorithm to apply the function
// to every element of the container:
for_each(v.begin(), v.end(), updater);
}


Share this post


Link to post
Share on other sites
Unfortunately, I believe Zahlman's code has a problem. Template parameters have to have external linkage (Which sucks, but then so does a lot of C++) - so that isn't standard code.

For example, Microsoft's C++ compiler produces this error on that snippet (if compiled with language extensions disabled):
Quote:

error C2918: 'update_word::<unnamed-type-updater>' : illegal use of local type in template instantiation


Moving the struct out of the function isn't considerably more work:

struct Updater
{
int id;

void operator()(CustomStruct& cs) const {
if (cs.id == id) {
cs.count++;
}
}
};

void update_word(int id, std::vector<CustomStruct>& v)
{
Updater updater = { id };

std::for_each(v.begin(), v.end(), updater);
}

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Unfortunately, I believe Zahlman's code has a problem. Template parameters have to have external linkage (Which sucks, but then so does a lot of C++) - so that isn't standard code.

For example, Microsoft's C++ compiler produces this error on that snippet (if compiled with language extensions disabled):
Quote:

error C2918: 'update_word::<unnamed-type-updater>' : illegal use of local type in template instantiation


I don't normally write it anonymously. I thought I saw ToohrVyk do something like that before :\ But that must have been in an example without a template?

It's seriously a problem because the vector is a template instantation? Wow, that really does suck.

Share this post


Link to post
Share on other sites

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