2015-07-09 13 views
6

Tworzę mapę tylko do celów edukacyjnych do przechowywania par klucz-wartość. Jeśli wydrukuję drugie pole mapy przy użyciu funkcji begin(), będę mógł wydrukować drugie pole mapy, ale gdy spróbuję zrobić to samo z ostatnim elementem mapy przy użyciu end(), nie będzie można wydrukować drugiego pola. Poniżej jest mój kod:Nie można uzyskać drugiego pola mapy przy użyciu końca()

#include <iostream> 
#include <cstdlib> 
#include <map> 
#include <string> 
#include <stdio.h> 


using namespace std; 

map<int,std::string> arr; 

map<int,std::string>::iterator p; 

int main(int argc, char** argv) { 

    arr[1] = "Hello"; 
    arr[2] = "Hi"; 
    arr[3] = "how"; 
    arr[4] = "are"; 
    arr[5] = "you"; 

    p = arr.begin(); 
    printf("%s\n",p->second.c_str()); 

    p = arr.end(); 
    printf("%s\n",p->second.c_str()); 

    return 0; 

} 
+3

dla kontenerów STL, ".end()" daje iteratorowi element "1-past-the-end-element" zobacz także: http: // stackoverflow.com/questions/15252002/what-is-the-the-the-the-end-iterator-in-stl-c – user2950911

Odpowiedz

2

Aby wydrukować ostatni element, użyj reverse iterator:

map< int,std::string>::reverse_iterator p; 
p = arr.rbegin(); 
if(p != arr.rend()) { 
    // Do whatever with, it points to the last element 
} else { 
    // map is empty 
} 

std::map::end zwróci iterator do jednego ostatniego ostatniego elementu i wyłuskania go zachowanie jest niezdefiniowane.

Od std::map::end na en.cppreference

Zwraca iterator do elementu po ostatnim elemencie pojemnika . Ten element działa jako symbol zastępczy; próba dostępu do niego powoduje niezdefiniowane zachowanie.

1

std :: SOMETHING.end() nie zwraca ostatni element, zwraca element, past-the-end. Sprawdź C++ documentation. W gruncie rzeczy to, co robisz, to próbowanie szacunku nieokreślonej lokalizacji pamięci.

6

Dereferencja end() jest jako end() zwraca iterator na 1 za koniec mapy. Jeśli chcesz ostatni element można użyć

p = --arr.end(); 

Nie można używać

p = arr.rbegin() 

jak nie można przypisać odwrotny iterator do przodu (iterator live example). Jeśli chcesz użyć rbegin(), musisz utworzyć odwrotny iterator.

map<int,std::string>::reverse_iterator rit; 
rit = arr.rbegin(); 

// or 

auto rit = arr.rebegin(); //C++11 or higher required for this 

Albo można przekonwertować go do przodu przy użyciu iteracyjnej this answer przez visitor

Jak zawsze należy sprawdzić, aby upewnić się, że masz ważny iterator. Jeśli kontener jest pusty begin() == end() i dereferencja jest niezdefiniowanym zachowaniem.

Źródło: http://en.cppreference.com/w/cpp/container/map/end

+1

"' begin() == end() '" - Myślę, że 'arr.empty()' jest bardziej przejrzysty . Może również być szybszy. –

+0

@ NOKER Po prostu pokazałem, że użycie 'begin()' jest takie samo jak 'end()' jeśli kontener jest pusty. – NathanOliver

2

Można użyć --arr.end() lub arr.rbegin().

arr.end() zwraca iterator do elementu za ostatnim elementem. Pozwala to na łatwiejsze zapisywanie pętli. Ten element służy wyłącznie do porównywania. Dereferencje nie są dozwolone.

1

Jak już wskazano w innych wpisach, end() jest iteratorem o jedną pozycję za ostatnim elementem na mapie. Dlatego nie powinieneś próbować zdobywać jego pól. Aby uzyskać ostatni element, możesz użyć rbegin().

Powiązane problemy