• Advertisement
Sign in to follow this  

const vectorstring&::iterator? BAH!

This topic is 4429 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

Hey I'm a little lost in my code here and I've never really used iterators before so this may be the stupidest question in the world :)
void TileEngine::LoadMap(const vector<string>& NewMap, int X, int Y)
  this->TilesX = X;
  this->TilesY = Y;
  this->World.assign(this->TilesX * this->TilesY, "Black");
  vector<string>::iterator IterMap, IterNew;
  for(IterMap = this->World.begin(), IterNew = NewMap.begin(); IterMap != this->World.end(); IterMap++, IterNew++)
    IterMap = IterNew;

Now I get an error on the for (7th) line
(99): error C2679: binary '=' : no operator found which takes a right-hand operand of type
'std::vector<_Ty>::const_iterator' (or there is no acceptable conversion)
So my guess is that it's the iterator to the passed vector that is causing the problem. I'm trying to copy the contents of NewMap into World. World is a private vector<string>. Could someone please enlighten me and save me from this mind rot. Sure there are probably lots of other ways to do this too, I'm open to suggestions. Thanks, much appreciated everyone! Jemburula

Share this post

Link to post
Share on other sites
Well the problem is that you're trying to copy an iterator into another iterator. You want to be copying the data that the individual iterators are pointing to, not the iterators themselves. The = operator is not overloaded for iterators. Try this (*IterMap) = (*IterNew). This should give you the actual data that the iterator is pointing to.

Share this post

Link to post
Share on other sites
Original post by Jemburula
Could someone please enlighten me and save me from this mind rot. Sure there are probably lots of other ways to do this too, I'm open to suggestions.

I'll go for the easy answer first, then the explanation of why what you were trying to do didn't work. The easy answer is: "other ways to do this? Sure, just a couple":
// The easiest - probably what you want
World = NewMap;

// an alternative - usually only used if you want to assign from
// a container of a different but convertible type (i.e. from a
// vector< int > to a vector< float >) or want to assign a
// subrange
World.assign(NewMap.begin(), NewMap.end());

I hadn't spotted your assign line. Assuming you want to copy all the elements of NewMap into World and then pad World to size TilesX * TilesY by inserting copies of the string "Black" and assuming NewMap could be larger or smaller than TilesX * TilesY the best technique I can think of would be:
// we're going to use this value a few times so lets give it a name
std::size_t worldSize = TilesX * TilesY;

// we know how big we want the array so lets reserve that space and potentially avoid a reallocation

// copy at most worldSize entries from NewMap into World
World.assign(NewMap.begin(), NewMap.begin() + std::min(NewMap.size(), worldSize));

// pad World upto worldsize
World.insert(NewMap.end(), worldSize - World.size(), "Black");


As for why you were getting the error you were, it's a matter of const correctness. NewMap was declared const (well, reference to const, same difference). This means that you can't change its contents. One of the ways it enforces this is by not allowing you to obtain a non-const iterator to itself (otherwise anything could use that iterator to modify the vector). Your assignment error is your compiler complaining that NewMap.begin() yields a vector< string >::const_iterator, which you are trying to assign to an object of just vector< string >::iterator. The compiler doesn't have a way to convert a const_iterator to a plain iterator.

Once you'd fixed that problem you come up with two more issues. One is that you never actually assign elements, your loop only copies the iterators around. This is going to be especially bad since IterMap is never going to equal World.end() unless World is empty. After the first iteration you've changed IterMap to point into NewMap, not World. To assign elements you need to dereference the iterators:
*IterMap = *IterNew;

Finally even if that was fixed the loop would only work if NewMap contained at least as many elements as World. It would only work correctly if NewMap and World contained exactly the same number of elements. It loops World.size() times. It therefore reads World.size() elements from each container. If either container does not contain exactly World.size() elements then either it will read past the end of the container (undefined behaviour) or it will not read all the elements of the container.


Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement