2009-07-25 36 views

Trả lời

77

Một số giữ ngắn quá. Cũng như một char đã ký.

Nhưng không có loại nào trong số đó được đảm bảo đủ lớn để thể hiện kích thước của bất kỳ chuỗi nào.

string::size_type đảm bảo điều đó. Nó là một loại đủ lớn để thể hiện kích thước của một chuỗi, bất kể chuỗi đó lớn đến cỡ nào.

Để biết ví dụ đơn giản về lý do tại sao điều này là cần thiết, hãy xem xét nền tảng 64 bit. Một int thường là 32 bit, nhưng bạn có nhiều hơn 2^32 byte bộ nhớ.

Vì vậy, nếu một (đã ký) int được sử dụng, bạn không thể tạo chuỗi lớn hơn 2^31 ký tự. Tuy nhiên, size_type sẽ là giá trị 64 bit trên các nền tảng đó, do đó, nó có thể đại diện cho các chuỗi lớn hơn mà không có vấn đề gì.

+1

Đó cũng là trường hợp trên PowerPC và Cell. Và, theo như tôi có thể nhớ lại, trên Alpha là tốt. Ngoài ra, tất nhiên, tôi nghĩ x64 là CPU * 64-bit điển hình trong những ngày này. ;) Nhưng bạn nói đúng, nó rõ ràng là phụ thuộc vào nền tảng. – jalf

+3

Nền tảng Linux 64 bit nào chúng ta đang nói đến ở đây? Trên máy x64, nó vẫn có int 32 bit cuối cùng tôi đã thử. Và trên bộ xử lý Cell, int cũng là 32 bit. Và bằng cách mở rộng, tôi giả định như vậy để áp dụng cho Linux trên PowerPC.Vì vậy, không, Linux ABI thay đổi từ nền tảng này sang nền tảng khác, và hầu hết các nền tảng mà tôi biết chỉ định ints 4 bit, ngay cả trên Linux. – jalf

+1

Nhưng bạn nói đúng. Phần cứng thường định nghĩa một ABI chung mà phần mềm * nên * theo để cho phép khả năng tương tác. Hệ điều hành xác định một ABI thường giống hệt nhau, nhưng có thể không. Và trình biên dịch thực sự thực hiện một ABI mà một lần nữa thường theo sau hệ điều hành, nhưng không nghiêm chỉnh nói phải. – jalf

7

Số lồng size_type typedef là yêu cầu đối với các thùng chứa tương thích STL (mà std::string xảy ra), vì vậy mã chung có thể chọn loại số nguyên chính xác để biểu thị kích thước.

Không có điểm nào khi sử dụng mã trong mã ứng dụng, size_t hoàn toàn ok (int không phải vì ký tên và bạn sẽ nhận được cảnh báo so sánh đã ký).

+2

Bạn có thể đi xa đến mức không có điểm nào? Có lẽ nếu bạn không muốn mã di động nhất thì bạn có thể sử dụng 'size_t'. Hoặc đối với hầu hết các tình huống thực tế ngày hôm nay bạn có thể lấy đi với 'size_t'. Nhưng nếu không có điểm nào, 'size_type' sẽ không tồn tại, bây giờ phải không? –

+1

'size_t' * được * đảm bảo đủ lớn, vì vậy tối đa bạn" lãng phí "một số dung lượng (trong sổ đăng ký hoặc trên ngăn xếp) để sử dụng giá trị lớn hơn mức cần thiết. Các typedef này được sử dụng trong mã chung, không phải khi sử dụng 'std :: string', là một mô hình cụ thể. Tức là, nếu bạn đang ở trong một hàm mẫu lấy một 'basic_string' tùy ý, đặc biệt là. với một phân bổ * tùy ý *, bạn nên sử dụng typedef lồng nhau. Nhưng có, không có điểm cho 'std :: string', bởi vì' size_t' là hoàn toàn ok. –

+0

'size_t' chưa được ký. Miễn là bạn so sánh với 'std :: string :: npos' (trái ngược với' pos> = 0'), bạn sẽ không sao. – Jason

19

Ví dụ mà bạn đã đưa ra,

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

là từ Accelerated C++ by Koenig. Ông cũng nêu lý do cho sự lựa chọn của mình ngay sau đó, cụ thể là:

Loại chuỗi :: định nghĩa size_type là tên của số loại thích hợp để giữ số ký tự trong một chuỗi. Bất cứ khi nào chúng ta cần một biến địa phương để chứa kích thước của một chuỗi, chúng ta nên sử dụng std :: string :: size_type làm kiểu biến đó.

Lý do chúng tôi đã cung cấp cho cols một loại std :: string :: size_type là để đảm bảo rằng cols có khả năng chứa số ký tự trong lời chào, cho dù số lượng đó lớn đến cỡ nào. Chúng tôi có thể chỉ đơn giản là đã nói rằng cols có loại int, và thực sự, làm như vậy có lẽ sẽ làm việc . Tuy nhiên, giá trị của cols phụ thuộc vào kích thước của đầu vào cho chương trình của chúng tôi và chúng tôi không thể kiểm soát thời lượng của đầu vào đó. Có thể hiểu rằng ai đó có thể cung cấp cho chương trình của chúng tôi một chuỗi quá dài rằng một int không đủ để chứa chiều dài của nó.

Các vấn đề liên quan