map, iterators and swap

K

kalita

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
 
N

Neil Cerutti

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.
 
G

Greg

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
 
K

kalita

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
 
H

Howard Hinnant

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top