Bất cứ ai có thể giải thích tại sao không phải là toán tử [] thực hiện cho một danh sách std ::? Tôi đã tìm kiếm xung quanh một chút nhưng không tìm thấy câu trả lời. Nó sẽ không quá khó để thực hiện hoặc tôi thiếu một cái gì đó?Tại sao không có toán tử [] cho danh sách std ::?
Trả lời
Lấy một phần tử theo chỉ mục là một hoạt động O (n) cho danh sách liên kết, đó là những gì std::list
là. Vì vậy, nó đã được quyết định rằng việc cung cấp operator[]
sẽ là lừa đảo, vì mọi người sẽ bị cám dỗ để chủ động sử dụng nó, và sau đó bạn sẽ thấy mã như:
std::list<int> xs;
for (int i = 0; i < xs.size(); ++i) {
int x = xs[i];
...
}
mà là O (n^2) - rất khó chịu. Vì vậy, tiêu chuẩn ISO C++ đề cập cụ thể rằng tất cả các chuỗi STL hỗ trợ operator[]
nên làm điều đó trong thời gian cố định phân bổ (23.1.1 [lib.sequence.reqmts]/12), có thể đạt được cho vector
và deque
, nhưng không phải list
.
Đối với trường hợp bạn thực sự cần điều đó đại loại như vậy, bạn có thể sử dụng std::advance
thuật toán:
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
Nó sẽ không quá khó (đối với người triển khai) nhưng nó sẽ là quá khó khăn trong thời gian chạy, vì hiệu suất sẽ là khủng khiếp trong hầu hết các trường hợp. Buộc người dùng đi qua từng liên kết sẽ làm cho nó rõ ràng hơn những gì đang xảy ra trong đó hơn 'myList [102452]' sẽ.
Để xây dựng một toán tử bit [] là hoạt động thời gian không đổi ở tất cả các vị trí khác được sử dụng. Việc đặt cùng tên cho một hoạt động O (n) sẽ không nhất quán và khó hiểu. – dmckee
Vâng, nó là O (log n) trong một bản đồ nhưng tôi nhận được quan điểm của bạn. –
Trong bản đồ, nó không phải là một chỉ số vị trí, điều này khá rõ ràng - ngoại trừ có lẽ khi khóa bản đồ là một số nguyên, nhưng nếu bạn khó hiểu về truy cập vị trí bằng tra cứu chính, bạn có nhiều vấn đề lớn hơn;) –
Tôi nghĩ rằng tôi đã tìm thấy câu trả lời trong một SO gửi Extending std::list
"nhà điều hành của bạn [] là O (N) thời gian "- điều này là chính xác lý do tại sao nó không được bao gồm trong tiêu chuẩn std :: danh sách <>. - Michael Burr ngày 14 tháng 12 tại 17:29
Tuy nhiên, đó có phải là lý do duy nhất không?
CHỈNH SỬA: Dường như mọi người đã đề cập đến nó là vấn đề nhất quán về hiệu suất sau đó thực hiện nghiêm ngặt.
Bạn có nghĩa là không đủ lý do? :-) –
Đó là. Tìm kiếm ở đâu đó, .NET 'LinkedList' không cung cấp một trình chỉ mục cho các lý do chính yếu - nó chỉ quá lừa đảo. Theo truyền thống, khi một cái gì đó có một chỉ mục vị trí, nó được giả định rằng hoạt động là O (1). –
Trên thực tế, có hoàn toàn không có lý do gì để không cung cấp operator [] hoặc ít nhất là phương pháp tại (int), vì hai lý do:
- Đây là danh sách liên kết đôi, vì vậy bạn cần phải di chuyển ở hầu hết kích thước()/2 nơi trình vòng lặp của bạn để lấy chỉ mục của bạn, và chi phí để giữ lại một vài vòng lặp cố định hơn là rất thấp. Và cuối cùng, thư viện Qt cung cấp toán tử [] và tại, và tôi không thấy chi phí hiệu năng sử dụng nó.
- buộc người khác không sử dụng là thói quen lập trình rất xấu, vì danh sách sẽ sử dụng nhiều thùng chứa, nếu bạn có quyền truy cập ngẫu nhiên gần quyền truy cập được liên kết, có nhiều ví dụ khi bạn cần cả hai quyền truy cập mà thời gian chạy.
Đây có phải là cơ sở hoàn toàn dựa trên ý kiến của bạn hoặc bạn đã tạo ra một kịch bản thử nghiệm tốt đẹp, nơi bạn cho thấy việc triển khai tuỳ chỉnh của bạn về 'std :: list
- 1. toán tử == và danh sách :: remove()
- 2. Tại sao không có thuật toán std :: copy_if?
- 3. Tại sao toán tử ++ trả về giá trị không const?
- 4. Tại sao không gán() giá trị cho một phần tử danh sách hoạt động trong R?
- 5. toán tử std :: string() const?
- 6. Không thể gán LinkedList cho Danh sách, tại sao?
- 7. Tại sao không @JsonUnwrapped làm việc cho Danh sách?
- 8. Tại sao không std :: pair có iterators?
- 9. Tại sao không phải là toán tử [] const cho các bản đồ STL?
- 10. Tại sao không có std :: stou?
- 11. Tại sao tôi không thể khởi tạo std :: vector với danh sách khởi tạo
- 12. Tại sao preallocation lại hữu ích cho danh sách?
- 13. Tại sao Danh sách Scala không có trường kích thước?
- 14. Xóa một std :: vector cần một toán tử gán. Tại sao?
- 15. sắp xếp std :: danh sách sử dụng std :: sort
- 16. Tại sao nó không sử dụng toán tử quá tải của tôi cho ++?
- 17. Tại sao có một toán tử sizeof ... trong C++ 0x?
- 18. Tại sao R không cho phép toán tử $ trên vectơ nguyên tử?
- 19. Cách áp dụng toán tử logic cho tất cả các phần tử trong danh sách python
- 20. Sử dụng toán tử toán tử danh sách (a :: b) làm hàm
- 21. Toán tử nhân được áp dụng cho danh sách (cấu trúc dữ liệu)
- 22. Tại sao gửi danh sách cho hợp tác dự án?
- 23. Toán tử khác biệt danh sách Haskell trong F #
- 24. lý do tại sao trình biên dịch là trì hoãn std :: danh sách deallocation?
- 25. Mục đích của toán tử ngôi sao khi được sử dụng trên Danh sách
- 26. Tại sao danh sách listener listener list?
- 27. sao chép danh sách python: có sự khác biệt giữa [cũ] và danh sách (cũ) không?
- 28. Tại sao có mức độ ưu tiên cho các toán tử như static_cast?
- 29. Tại sao một lớp dẫn xuất không sử dụng toán tử lớp cơ sở = (toán tử gán)?
- 30. Tại sao có Danh sách <T> .BinarySearch (...)?
Vì vậy, về cơ bản, nó chỉ là vấn đề ngăn chặn người phạm sai lầm? –
yep.Hoặc không hứa hẹn bạn không thể giữ được. Trong STL, toán tử [] hứa hẹn * hiệu quả * truy cập vào các phần tử tùy ý. – jalf
Và cảm ơn Pavel đã tham khảo chuẩn C++! –