herzl shemuelian
herzl shemuelian

Reputation: 3498

How can I check if this is last member of std::list?

I have a list like below

typedef std::list<std::string> SegmentValue;

then in a iteration I need check if this is last iteration.

     for(Field::SegmentValue::const_iterator it = m_segmentValue.begin();It != 
           m_segmentValue.end();It++){
              if((segIt + 1) == m_segmentValue.end())//last iteration
              ...
        }

but I get error in compile that:

 error C2678: binary '+' : no operator found which takes a left-hand operand of type 'std::list<_Ty>::_Const_iterator<_Secure_validation>'

how I can check if this is last itration?

Upvotes: 1

Views: 153

Answers (6)

Marshall Clow
Marshall Clow

Reputation: 16670

How about:

if ( &*it == &*(m_segmentValue.rbegin()))

i.e, comparing the addresses of the segments.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320421

You can't use binary + and - operators with std::list iterators. std::list iterators are bidirectional iterators, but they are not random access iterators, meaning that you can't shift them by an arbitrary constant value.

Use unary ++ and -- instead

Field::SegmentValue::const_iterator it_last = m_segmentValue.end();
--it_last;

Now it_last is the last element iterator. Just make sure it remains valid. If you are not making any iterator-invalidating modifications to your container, you can pre-compute it_last and use it in the cycle. Otherwise, you'll have to re-compute it as necessary.

In fact, in generic algorithms it is always a good idea to prefer using -- and ++ with iterators whenever possible (instead of binary + 1 and - 1), since it reduces your algorithm's requirements: binary + and - require random access iterators, while ++ and -- work with bidirectional ones.

Upvotes: 4

jrok
jrok

Reputation: 55395

Something like this perhaps:

Field::SegmentValue::const_iterator last = m_segmentValue.end()
--last;

for(Field::SegmentValue::const_iterator it = m_segmentValue.begin();
    It != m_segmentValue.end();
    It++) {

        if(It == last) {
            // last iteration
        }     
    }

You can only do arithmetic with Random Access Iterators. std::list's iterators are Bidirectional.

See here for what you can and cannot do with iterators of various categories.

Upvotes: 1

ecatmur
ecatmur

Reputation: 157344

Use std::next:

if (std::next(segIt) == m_segmentValue.end()) ...

If you're using C++03, you can easily write next yourself:

template<typename T> T next(T it, typename std::iterator_traits<T>::difference_type n = 1) {
    std::advance(it, n);
    return it;
}

Upvotes: 2

Alessandro Teruzzi
Alessandro Teruzzi

Reputation: 3978

std::list iterator are not random access, they are bidirectional. The operator+ is not supported. You need to use std::vector to do something like that.

Upvotes: 0

Andrew Durward
Andrew Durward

Reputation: 3861

Try this:

Field::SegmentValue::const_iterator next = it; ++next;
// or in C++11:
// Field::SegmentValue::const_iterator next = std::next( it );
if( next == m_segmentValue.end()) //last iteration

List iterators are Bidirectional, not RandomAccess so they don't support operator+.

Upvotes: 0

Related Questions