2013-03-02 19 views
9

Próbowałem indeksować vector przy użyciu ujemnego indeksu. Funkcja składowa vector::at() sprawdza, czy określony indeks znajduje się w granicach wektora, a jeśli to nie nastąpi, zostanie zgłoszony wyjątek out_of_range.Indeksowanie std :: wektor z ujemnym indeksem

vector<float> array; // sample vector 
array.push_back(0.123); 
array.push_back(1.234); 
array.push_back(2.345); 
array.push_back(3.456); 
array.push_back(4.567); 

int index = -1; 
float f = array.at(index); 
cout << f << endl; 

Podpis vector::at() funkcji użytkownik wymaga określonego parametru jest vector<T>::size_type typu, a tego typu unsigned int do wektora, tak że kompilator powinien wykonać niejawnego konwersji z int (typ zmiennej index) do unsigned int. Ponieważ wartość index jest -1 w powyższym przykładzie niejawnie przekształca index jest 4294967295 (to jest maksymalna wartość typu unsigned int): wartość ta jest przekazywana do funkcji vector::at() człon, który zgłasza wyjątek out_of_range.

Innymi słowy, wyjątek nie jest wyrzucane, ponieważ funkcja vector::at() element widzi, że index jest mniejsza od zera, lecz ponieważ pośrednio przekształca index jest większa niż bieżąca wielkości vector. Czy to jest poprawne wytłumaczenie?

+0

Tak, zasadniczo. – Dave

+0

Tak, to jest właściwe wytłumaczenie. – syam

Odpowiedz

8

Tak, to jest poprawne wyjaśnienie. (Z wyjątkiem at pobiera vector::size_type, zwykle std::size_t, który jest pewnym nieokreślonym, nie podpisanym typem całkowitym (zwykle jest to szerokość bitowa wskaźników w twoim systemie). Jest to dozwolone w twoim systemie, ale nie jest wymagane przez standard; 32-bitowe unsigned int z 64-bitowe size_t jest powszechne.)

Na marginesie, zachowaj ostrożność z konwersją bez znaku do podpisu: standard nie wymaga, aby była to podróż w obie strony podpisana-> unsigned-> podpisana dla wartości ujemnych, a niektóre kompilatory agresywnie optymalizować w nieoczekiwany sposób.

+0

Co to znaczy, że standard nie wymaga, aby był odwrotnością wartości ujemnych_? – enzom83

+4

'(int) (unsigned) -1 == -1' nie musi być prawdziwe. – Yakk

+0

"niektóre kompilatory agresywnie optymalizują się w nieoczekiwany sposób" - ta konwersja jest * zdefiniowana przez implementację *, więc nie powinno być żadnych niespodzianek optymalizacyjnych. –