STL container map trying to get the last iterator of map

Hello ,

I was trying to access the last element of the map using an iterator using below approach

std:: iterator last_butone_elem = someMap.end();

for (iter = someMap.begin(); iter != someMap.end(); ++iter) {
// do something for all iterations
if (iter = --last_butone_elem) {
++iter;
// do something for all but only for the last iteration
}

Problem I am facing: The below approach is working fine for odd number of map elements but not for even number of elements in map.I mean its not entering inside if condition for odd number of elements of my map.

I do not have any idea , why it is behaving like this. Could some one please help me resolving this problem?
Last edited on
> I do not have any idea , why it is behaving like this.

The iterator last_butone_elem is being decremented each time through the loop.
To get to the last element, decrement it just once, before the loop starts.


1
2
3
4
5
6
7
8
9
10
11
12
template < typename ORDERED_MAP > auto last_element_of( ORDERED_MAP& map )
{
    auto iter = map.end() ;
    return map.empty() ? iter : --iter ;
}

template < typename ORDERED_MAP, typename FN >
void for_all_but_last( ORDERED_MAP& map, FN fn )
{
    const auto iter_last = last_element_of(map) ;
    for( auto iter = map.begin() ; iter != iter_last ; ++iter ) fn(*iter) ;
}

http://coliru.stacked-crooked.com/a/c99d98e140e21a5c
Last edited on
if (iter = --last_butone_elem)
you're using assignment, not checking for equality. And you don't need to declare an additional iterator last_butone:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <map>

int main ()
{
  std::map<char,int> mymap;

  mymap['x'] = 100;
  mymap['y'] = 200;
  mymap['z'] = 300;

  // show content:
  std::map<char,int>::iterator rit;
  for (rit=mymap.begin(); rit!=--mymap.end(); ++rit)
    std::cout << rit->first << " => " << rit->second << '\n';

  return 0;
}
> you're using assignment, not checking for equality.

I presume that is a typo (= instead of ==), because otherwise the code wouldn't compile.
(There is no conversion from iterator to bool).
Hello,

Thanks everyone for your quick feedback.

@JLBorges and @gunnerfunner
I am not using c++11 compiler. if i not wrong Auto keyword is specific to c++11.

May be my question is not clear.
I need to print all the elements in my map to console in one format and only the last element in another format. So with in the iterator I wanted to modify the last element using "if" condition (checking for last before element ) and print my last element in a different format to the console.

With the solutions proposed above , either I can iterate through only till my last but one element or my map elements in reverse order . But my intention is different(mentioned in above paragraph).

C++98:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template < typename ORDERED_MAP >
typename ORDERED_MAP::const_iterator last_element_of( const ORDERED_MAP& map )
{
    typename ORDERED_MAP::const_iterator iter = map.end() ;
    return map.empty() ? iter : --iter ;
}

template < typename ORDERED_MAP > void print( const ORDERED_MAP& map )
{
    const typename ORDERED_MAP::const_iterator iter_last = last_element_of(map) ;

    // print first n-1 elements in one format
    for( typename ORDERED_MAP::const_iterator iter = map.begin() ; iter != iter_last ; ++iter )
        std::cout << '{' << iter->first << ',' << iter->second << "} " ;

    // print the last element in a different format
    if( iter_last != map.end() )
        std::cout << "and finally ![{" << iter_last->first << ',' << iter_last->second << "}]!\n" ;
}

http://coliru.stacked-crooked.com/a/3e32b65eae41f6a8
Thanks a lot JLBorges ,

With an example with templates , you made my work much simpler .
Topic archived. No new replies allowed.