2013-02-12 37 views
10

Tại sao std::string có chức năng thành viên find trong khi std::vector và bạn bè không có nó?Tại sao `std :: string` lại có hàm` find` thành viên?

Có điều gì sai khi sử dụng std::find trên chuỗi không?

+13

http://www.gotw.ca/gotw/084.htm – juanchopanza

+2

@juanchopanza wow đó là một liên kết tuyệt vời . Đối với những người không đọc tác giả lập luận rằng nhiều hàm thành viên có thể được loại bỏ khỏi các lớp, chẳng hạn như trống từ std :: list, std :: vector, std: : chuỗi và được tạo thành một hàm chung phục vụ toàn bộ thư viện chuẩn). – nckturner

Trả lời

12

Đó chủ yếu là vì lý do lịch sử, nhưng không chỉ.

Thư viện chuỗi và STL (thư viện container/thuật toán được phát triển bởi A. Stepanov đã trở thành một phần của Thư viện chuẩn C++) được phát triển độc lập và áp dụng các quy ước khác.

Tuy nhiên, kể từ khi họ cuối cùng cả hội tụ vào Thư viện chuẩn C++, cáC++ chuẩn C không thực hiện một nỗ lực nhằm thống nhất những công ước cú pháp và cho phép sử dụng string s với các thuật toán STL, đó là lý do lớp string có chức năng thành viên như begin()end() ngoài các chức năng thành viên khác như substr().

Ngoài khả năng tương thích ngược, dù sao, còn có một lý do tại sao string cung cấp chức năng thành viên như find(): không giống như container, mà có nghĩa là để làm việc với các thuật toán chung mà truy cập hoặc thao tác yếu tố của họ, dây chủ yếu coi như giá trị bản thân thay vì là bộ sưu tập giá trị (tức là chuỗi char s). Vì vậy, nó có ý nghĩa để đóng gói các thuật toán thao tác các giá trị string thành các hàm thành viên của lớp string.

Trong thiết kế của nó, Thư viện chuẩn C++ hỗ trợ cả hai chế độ xem này là string s: là tập hợp giá trị và dưới dạng giá trị.

UPDATE:

Các bit của câu đầu tiên của bạn "trong khi std::vectorvà bạn bè không có nó" không phải là hoàn toàn chính xác. Ít nhất, không phải nếu bạn mở rộng phạm vi bạn bè của std::vector thành std::set, , std::map, std::multimap, std::unordered_setstd::unordered_map (nói cách khác, khá nhiều cho tất cả các vùng chứa liên kết trong Thư viện chuẩn C++).

Một số cấu trúc dữ liệu nhất định có một phiên bản chức năng thành viên của một số thuật toán STL chung trên giao diện của chúng: điều này cho thấy thực tế là các thuật toán đó có hiệu quả hơn so với các đối tác chung của chúng. find()) hoặc triển khai chuyên biệt là cần thiết vì không thể áp dụng thuật toán chung cho các cấu trúc dữ liệu đó (ví dụ: std::remove(), trong đó sửa đổi giá trị trong vùng chứa).

4

Ngữ nghĩa của std::string::find(*) hoàn toàn khác với ngữ nghĩa của std::find. Trong trường hợp của thuật toán, nó sẽ tìm thấy một phần tử bên trong vùng chứa, nếu bạn áp dụng cho một số std::string có nghĩa là tìm vị trí mà ký tự đó là X.

Các chức năng thành viên std::string::find (ngoại trừ một biến thể mà phải mất một đơn charT) có một mục đích khác nhau, họ tìm chuỗi con (ví dụ: một chuỗi các giá trị chứ không phải là một giá trị duy nhất).

Câu hỏi tiếp theo sẽ là lý do tại sao một quá tải mất charT là có, khi đó có thể chỉ là một cuộc gọi đến std::find. Như Andy đã đề cập đến trong câu trả lời của anh ta, việc thực hiện STL và các thư viện chuỗi xảy ra tách biệt nhau. Lặp lại sau đó được thêm vào thành phần std::string. Bởi các vòng lặp thời gian đã được thêm vào std::string, sự quá tải này đã ở đó, ngay cả khi không, ngữ nghĩa vẫn khác một chút so với std::find trong đó như phần còn lại của std::string::find, thay vì các trình lặp mà chúng lấy và trả về vị trí . Điều này không có nghĩa là người ta không thể được thực hiện về mặt khác, chỉ có mã đó sẽ phức tạp hơn.

(*) Gấu với tôi ... đọc std::string như thể nó đã được đánh vần std::basic_string<>

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