2009-07-25 19 views

Odpowiedz

77

Krótka liczba zawiera również liczby. Podobnie jak podpis char.

Ale żaden z tych typów nie jest wystarczająco duży, aby reprezentować rozmiary dowolnych ciągów.

string::size_type gwarantuje to. Jest to typ, który jest wystarczająco duży, aby reprezentować rozmiar ciągu, bez względu na to, jak duży jest ten ciąg.

Dla prostego przykładu, dlaczego jest to konieczne, należy rozważyć platformy 64-bitowe. Typ int jest zazwyczaj nadal 32-bitowy, ale masz znacznie więcej niż 2^32 bajty pamięci.

Więc jeśli użyto (podpis) int, nie można utworzyć ciągów większych niż 2^31 znaków. size_type będzie wartością 64-bitową na tych platformach, więc może reprezentować większe ciągi bez problemu.

+1

Jest tak również w przypadku procesorów PowerPC i Cell. I, o ile pamiętam, również na Alphie. Dodatkowo, oczywiście, myślę, że x64 jest * typowym * 64-bitowym CPU w dzisiejszych czasach. ;) Ale masz rację, to oczywiście zależy od platformy. – jalf

+3

O której 64-bitowej platformie Linux mówimy? Na maszynach x64 nadal miałem 32-bitowy int. A w procesorach Cell int ma również 32 bity. I przez to, zakładam, że to samo odnosi się do Linuksa na PowerPC.Więc nie, Linux ABI różni się w zależności od platformy, a większość platform, które znam, określa 4-bitowe int, nawet na Linuksie. – jalf

+1

Ale masz rację. Sprzęt zazwyczaj określa wspólną ABI, którą oprogramowanie * powinno * stosować, aby umożliwić współdziałanie. System operacyjny definiuje ABI, która jest zwykle identyczna, ale może nie być. I kompilator faktycznie implementuje ABI, która ponownie zwykle podąża za systemem operacyjnym, ale nie musi tego koniecznie. – jalf

7

zagnieżdżone size_type typedef jest wymagane dla pojemników STL kompatybilny (co std::string dzieje się), tak, ogólny kod może wybrać odpowiedni rodzaj całkowitą reprezentowania rozmiarach.

Nie ma sensu go używać w kodzie aplikacji, o size_t jest zupełnie ok (int nie jest, ponieważ jest podpisany, a otrzymasz podpisany/unsigned ostrzeżenia porównanie).

+2

Czy można posunąć się do stwierdzenia, że ​​nie ma sensu? Być może, jeśli nie chcesz najbardziej przenośnego kodu, możesz użyć 'size_t'. Lub w większości praktycznych sytuacji dzisiaj możesz uciec z 'size_t'. Ale jeśli nie ma sensu, "size_type" nie istnieje, czyż nie? –

+1

'size_t' * jest * gwarantowane jest wystarczająco duże, więc co najwyżej" marnujesz "trochę miejsca (w rejestrze lub na stosie), aby użyć wartości większej niż niezbędna. Te typedefs są używane w kodzie ogólnym, a nie w przypadku użycia 'std :: string', który jest konkretnym modelem. Oznacza to, że jeśli jesteś w funkcji szablonu, biorąc arbitralne 'basic_string', esp. z dowolnym * przydzielającym *, należy użyć zagnieżdżonego typedef. Ale tak, nie ma sensu dla 'std :: string', ponieważ' size_t' jest całkowicie w porządku. –

+0

'size_t' jest unsigned. Tak długo jak porównujesz z 'std :: string :: npos' (w przeciwieństwie do' pos> = 0'), powinieneś być w porządku. – Jason

19

przykład, że dałeś,

const std::string::size_type cols = greeting.size() + pad * 2 + 2; 

wynosi od Accelerated C++ by Koenig. On również wskazuje powody swego wyboru tuż po tym, mianowicie:

typ std :: string określa size_type się nazwę odpowiedniego typu dla gospodarstwa liczbę znaków w ciągu. Ilekroć potrzebujemy lokalnej zmiennej , aby pomieścić rozmiar ciągu, powinniśmy użyć std :: string :: size_type jako typu tej zmiennej.

Dlatego, że daliśmy Cols typ std :: string :: size_type jest aby upewnić się, że jest w stanie cols zawierające liczbę znaków na powitanie, bez względu na to, jak duża liczba ta może być. Moglibyśmy po prostu powiedzieć, że cols ma typ int, i rzeczywiście, robiłby to prawdopodobnie praca . Jednak wartość cols zależy od wielkości wejścia do naszego programu i nie mamy żadnej kontroli nad tym, jak długo może to być wejście. Można sobie wyobrazić, że ktoś może dać naszemu programowi tak długi łańcuch , że int jest niewystarczający, by zawrzeć jego długość.