container idiom revisited

K

keith

I'd like all of you to take a look at page 471 of the ISO-IEC-14882
(2003) standard, where you are going to see things like:

*--c.end() and c.erase(--c.end())

I'd like you to comment on this. Maybe you were not right in claiming
the idiom was not well-formed and not portable?
 
K

keith

It's a defect in the standard. See, e.g, issue 355 in:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1685.html

Also: the bug has been fixed in the draft for C++0X.

I see. How then to erase the last element of a std::multimap<>? I've
tried mmap.erase(mmap.rbegin());, but it does not work.
mmap.erase(--mmap.end()), does work however. I don't see the construct
being wrong for a std::multimap<>::iterator (or any other associate
iterator), because they are not random but bidirectional. Consequently I
see them being of class type.
 
R

red floyd

I see. How then to erase the last element of a std::multimap<>? I've
tried mmap.erase(mmap.rbegin());, but it does not work.
mmap.erase(--mmap.end()), does work however. I don't see the construct
being wrong for a std::multimap<>::iterator (or any other associate
iterator), because they are not random but bidirectional. Consequently I
see them being of class type.

Assuming the map is not empty,

mmap.erase(mmap.rbegin().base)
 
K

Kai-Uwe Bux

keith said:
I see. How then to erase the last element of a std::multimap<>? I've
tried mmap.erase(mmap.rbegin());, but it does not work.
mmap.erase(--mmap.end()), does work however. I don't see the construct
being wrong for a std::multimap<>::iterator (or any other associate
iterator), because they are not random but bidirectional. Consequently I
see them being of class type.

a) Whether std::multimap<>::iterator is of class type is of no consequence
since operator-- does not need to be implemented as a member function
[17.3.1.2/3]. If it is a free function, the temporary mmap.end() will not
bind to its argument.

b) As for how to erase the last element: you can use a little helper
function:

template < typename Iter >
Iter prev ( Iter i ) {
-- i;
return ( i );
}

and then say: mmap.erase( prev( mmap.end() ) ). Of course, you can also
ditch the goal of doing it in one line :)


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

red said:
Assuming the map is not empty,

mmap.erase(mmap.rbegin().base)

Isn't mmap.rbegin().base() == mmap.end() as per the identify

&*(reverse_iterator(i)) == &*(i - 1)


Best

Kai-Uwe Bux
 
R

red floyd

Isn't mmap.rbegin().base() == mmap.end() as per the identify

  &*(reverse_iterator(i)) == &*(i - 1)

Best

Kai-Uwe Bux

Oops.

I think the concept is valid, though, if poorly implmented in my q&d
example.

map::reverse iterator it = mmap.rbegin();
++it;
mmap.erase(it.base());
 
J

James Kanze

I see. How then to erase the last element of a std::multimap<>?

std::multimap<>::iterator i = m.end();
-- i;
m.erase(i);

It isn't too difficult (and is generally useful) to write a
generic pred() function which can be used.
I've tried mmap.erase(mmap.rbegin());, but it does not work.

Rather obviouslym since multimap<>::erase expects a
multimap said:
mmap.erase(--mmap.end()), does work however.

On some (most? all?) implementations.
I don't see the construct being wrong for a
std::multimap<>::iterator (or any other associate iterator),
because they are not random but bidirectional. Consequently I
see them being of class type.

And? Class type doesn't guarantee that --mmap.end() will work.
 
K

keith

template < typename Iter >
Iter prev ( Iter i ) {
-- i;
return ( i );
}

and then say: mmap.erase( prev( mmap.end() ) ). Of course, you can also
ditch the goal of doing it in one line :)

Are prev() and next() part of boost or STL? They would resolve the
defect in the C++ 2003 standard nicely, from what I can see.
 
K

Kai-Uwe Bux

keith said:
Are prev() and next() part of boost or STL? They would resolve the
defect in the C++ 2003 standard nicely, from what I can see.

It is in the draft n3090 [24.4.4].


Best

Kai-Uwe Bux
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top