[SOLVED] Assigning Iterator to Iterator

Started by
18 comments, last by Sanctux 14 years, 3 months ago
I'm getting a debug assertion "vector iterators incompatible" so I traced it down. I discovered that when I step over in this line
activeItem = menuItems.begin(); // where activeItem is a vector iterator and a member variable of Menu and menuItems is a vector

activeItem has a member (error) with value 0 Then I went over to the constructor (activeItem is a member variable of Menu), activeItem still had a member (error) with value 0. What's up with this? Are iterators required to be initialized or something? [Edited by - Sanctux on December 24, 2009 2:33:42 AM]
Jack
Advertisement
While you say they are vector iterators, that is not enough to fully specify their type. vector<int>::iterator and vector<double>::iterator are both "vector iterators" but it doesn't mean they are compatible.
Thanks for the reply, stonemetal.

Here's what I have:
typedef std::pair<int, MenuItem> MenuPair;typedef std::vector<MenuPair> MenuVec;typedef MenuVec::iterator MenuIter;class Menu{// ...private:// ...	MenuVec menuItems;	MenuIter activeItem;// ...};


I'm pretty sure they're the same type of iterators; unless I got lost in the typedefs. [totally]
Jack

What is the condition that's triggering that assert? That will tell us why it thinks they are "incompatible"...

Could be a bug in the library
This triggers the assert:
if (activeItem == menuItems.begin())
Jack
Is the function this code is being run in a const member function?
If so that would cause the const version of menuItems.begin() to be called, returning a const_iterator, not an iterator.
I mean the library code that trips that assert, likely somewhere in <vector> - callstack should tell you
Quote:Original post by diablos_blade
Is the function this code is being run in a const member function?

Nope.

Here's the source of the assertion (in vector):
void _Compat(const _Myt& _Right) const	{	// test for compatible iterator pair	if (this->_Mycont == 0 || this->_Mycont != _Right._Mycont)		{		_DEBUG_ERROR("vector iterators incompatible");		_SCL_SECURE_INVALID_ARGUMENT;		}	}


In case it might help, further up the call stack:
	bool operator==(const _Myt& _Right) const		{	// test for iterator equality #if _HAS_ITERATOR_DEBUGGING		_Compat(_Right); #else		_SCL_SECURE_VALIDATE(this->_Has_container() && this->_Same_container(_Right)); #endif /* _HAS_ITERATOR_DEBUGGING */		return (_Myptr == _Right._Myptr);		}



Thanks for the replies! [smile]
Jack
Was one of the iterators assigned to a different container previously?

What is the value of _Mycont for each iterator when it asserts?

Can you check operator= for the iterator to make sure it assigns the _Mycont member?
Quote:Original post by RDragon1
Was one of the iterators assigned to a different container previously?

What is the value of _Mycont for each iterator when it asserts?

Can you check operator= for the iterator to make sure it assigns the _Mycont member?

1. Well, the only time I did anything else with activeItem was here:
activeItem = menuItems.begin();
which is called before the point of assertion. Otherwise, I don't think I've touched it.

2. this->_Mycont has value 0x00000000 and its member _Myfirstiter has CXX0030: Error: expression cannot be evaluated. _Right._Mycont has value 0x056a4844.

3. Here's operator=:
	_Myt& operator=(const _Myt& _Right)		{	// assign _Right		if (this != &_Right)			{	// worth doing #if _HAS_ITERATOR_DEBUGGING			this->_Orphan_all(); #endif /* _HAS_ITERATOR_DEBUGGING */			if (_Right.size() == 0)				clear();	// new sequence empty, erase existing sequence			else if (_Right.size() <= size())				{	// enough elements, copy new and destroy old				pointer _Ptr = _STDEXT unchecked_copy(_Right._Myfirst, _Right._Mylast,					_Myfirst);	// copy new				_Destroy(_Ptr, _Mylast);	// destroy old				_Mylast = _Myfirst + _Right.size();				}			else if (_Right.size() <= capacity())				{	// enough room, copy and construct new				pointer _Ptr = _Right._Myfirst + size();				_STDEXT unchecked_copy(_Right._Myfirst, _Ptr, _Myfirst);				_Mylast = _Ucopy(_Ptr, _Right._Mylast, _Mylast);				}			else				{	// not enough room, allocate new array and construct new				if (_Myfirst != 0)					{	// discard old array					_Destroy(_Myfirst, _Mylast);					this->_Alval.deallocate(_Myfirst, _Myend - _Myfirst);					}				if (_Buy(_Right.size()))					_Mylast = _Ucopy(_Right._Myfirst, _Right._Mylast,						_Myfirst);				}			}		return (*this);		}

and
	_Mytype& operator=(const _Mytype& _Right)		{	// assign _Vb_reference _Right to bit		return (*this = bool(_Right));		}	_Mytype& operator=(bool _Val)		{	// assign _Val to bit		if (_Val)			*_Getptr() |= _Mask();		else			*_Getptr() &= ~_Mask();		return (*this);		}


Thanks!
Jack

This topic is closed to new replies.

Advertisement