By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,905 Members | 1,265 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,905 IT Pros & Developers. It's quick & easy.

map, iterators and swap

P: n/a
Hi All,

typedef std::list<int> Cont;
void f(Cont &c1, Cont &c2)
{
Cont::iterator it = c1.begin();
c1.swap(c2);
it == c2.begin(); // is this ill formed?
}

Visual C++ 2005 has fancy iterator debugging, and it asserts at the
last line saying that iterators are incompatible and cannot be
compared. Basically, when in debugging mode it stores pointer to
container with each iterator, and this pointer obviously still points
to c1 despite the swap, so comparison with iterator obtained from
c2.begin() fails.

Could somebody enlighten me if this is correct behaviour (i.e. the code
is ill formed), or if this is VC 2005 bug.

cheers,
Marcin

Oct 25 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On 2005-10-25, ka****@poczta.onet.pl <ka****@poczta.onet.pl> wrote:
Hi All,

typedef std::list<int> Cont;
void f(Cont &c1, Cont &c2)
{
Cont::iterator it = c1.begin();
c1.swap(c2);
it == c2.begin(); // is this ill formed?
}

Could somebody enlighten me if this is correct behaviour (i.e.
the code is ill formed), or if this is VC 2005 bug.


According to Dinkumware's standard libary documentation it is
well formed when c1.allocator == c2.allocator.

I wouldn't call it a VC bug. In most cases, comparing iterators
from two different containers would be an error.

--
Neil Cerutti
Oct 25 '05 #2

P: n/a

ka****@poczta.onet.pl wrote:
Hi All,

typedef std::list<int> Cont;
void f(Cont &c1, Cont &c2)
{
Cont::iterator it = c1.begin();
c1.swap(c2);
it == c2.begin(); // is this ill formed?
}

Visual C++ 2005 has fancy iterator debugging, and it asserts at the
last line saying that iterators are incompatible and cannot be
compared. Basically, when in debugging mode it stores pointer to
container with each iterator, and this pointer obviously still points
to c1 despite the swap, so comparison with iterator obtained from
c2.begin() fails.

Could somebody enlighten me if this is correct behaviour (i.e. the code
is ill formed), or if this is VC 2005 bug.


Comparing iterators from different containers is an open C++ library
issue (#446) but the intention is apparently that such comparisons are
undefined.

However, the comparison in the program above should be OK (at least in
practice) since the containers have been swapped and the iterators
being compared are std::list iterators which are not easily prone to
invalidation.

Greg

Oct 25 '05 #3

P: n/a
> ka****@poczta.onet.pl wrote:
Hi All,

typedef std::list<int> Cont;
void f(Cont &c1, Cont &c2)
{
Cont::iterator it = c1.begin();
c1.swap(c2);
it == c2.begin(); // is this ill formed?
}
Comparing iterators from different containers is an open C++ library
issue (#446) but the intention is apparently that such comparisons are
undefined.

However, the comparison in the program above should be OK (at least in
practice) since the containers have been swapped and the iterators
being compared are std::list iterators which are not easily prone to
invalidation.


Yes in practice it works everywhere I tested except in VS2005 when
iterator debugging is on. But my question is if calling swap does make
the above comparison legal. In other words what are the sematics of
iterator after swap? Should I treat it as iterator to the old container
(even though it now points to element in new container), and apply rule
about comparing iterators from different containers? Sigh...
From what I know, the standard says only std::basic_string iterators

are invalidated by swap. Iterators from the rest of the containers
should be untouched. But what about my comparison failing then?

cheers,
Marcin

Oct 25 '05 #4

P: n/a
In article <11**********************@g14g2000cwa.googlegroups .com>,
ka****@poczta.onet.pl wrote:
Hi All,

typedef std::list<int> Cont;
void f(Cont &c1, Cont &c2)
{
Cont::iterator it = c1.begin();
c1.swap(c2);
it == c2.begin(); // is this ill formed?
}

Visual C++ 2005 has fancy iterator debugging, and it asserts at the
last line saying that iterators are incompatible and cannot be
compared. Basically, when in debugging mode it stores pointer to
container with each iterator, and this pointer obviously still points
to c1 despite the swap, so comparison with iterator obtained from
c2.begin() fails.

Could somebody enlighten me if this is correct behaviour (i.e. the code
is ill formed), or if this is VC 2005 bug.
This is simply a bug in the debugging STL. A container swap should also
swap the iterator owners (in debug mode). No, you won't find that in
the standard, the standard doesn't address debug mode. But the standard
does say:
no swap() function invalidates any references, pointers, or iterators
referring to the elements of the containers being swapped.


In the implementation I'm running on, in debug mode, the ownership test
is executed and passes.

-Howard
Oct 25 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.