Iterator to last element in list?

H

Howard

Is there an easy way to get an iterator (*not* a reverse-iterator) to the
last element in a list? The last() function returns the element itself, not
an iterator.

Thanks,
-Howard
 
I

Ian Collins

Howard said:
Is there an easy way to get an iterator (*not* a reverse-iterator) to
the last element in a list? The last() function returns the element
itself, not an iterator.
How about list.end()-1 or list.start()+(list.size()-1)
 
M

Mark P

Ian said:
How about list.end()-1 or list.start()+(list.size()-1)

list iterators are bidirectional, not random access, so you can't do
arithmetic like this. Not to mention that list.size() is O(n).

But you can do:

list<T>::iterator it = l.end();
if( !l.empty())
--it;

Now "it" points to either the last element or, if the list is empty, end().
 
I

Ian Collins

Mark said:
list iterators are bidirectional, not random access, so you can't do
arithmetic like this. Not to mention that list.size() is O(n).
Oops, sorry.
 
H

Howard

Mark P said:
list iterators are bidirectional, not random access, so you can't do
arithmetic like this. Not to mention that list.size() is O(n).

But you can do:

list<T>::iterator it = l.end();
if( !l.empty())
--it;

Now "it" points to either the last element or, if the list is empty,
end().

Yeah, that's what I'm doing now, but I was hoping for a single expression I
could use. This is working fine.

Thanks,
-Howard
 
D

Daniel T.

"Howard said:
Yeah, that's what I'm doing now, but I was hoping for a single expression I
could use. This is working fine.

assert( !l.empty() );
list<T>::iterator it = --l.end();
 
D

Daniel T.

"Howard said:
Yeah, that's what I'm doing now, but I was hoping for a single expression I
could use. This is working fine.

Or how about:

assert( !l.empty() );
list<T>::iterator it = l.rend().base();
 
K

Kai-Uwe Bux

Daniel said:
assert( !l.empty() );
list<T>::iterator it = --l.end();

I prefer your other idea:

list<T>::iterator it = l.rbegin().base();

This is more generic, e.g. you can use it in algorithms templated on
containers:

template < typename Container >
typename Container::iterator
last_iter ( Container & c ) {
return ( c.rbegin().base() );
}

will always work whereas

template < typename Container >
typename Container::iterator
last_iter ( Container & c ) {
return ( -- c.end() );
}

can fail for std::vector where the iterator type might be a naked pointer.



Best

Kai-Uwe Bux
 
P

Pete Becker

assert( !l.empty() );
list<T>::iterator it = --l.end();

Maybe, but it's not required to work. l.end() returns a temporary, and
-- isn't required to be a member function. It usually is, so this will
work with most implementations.

list<T>::iterator it = l.end();
--it;
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top