2012-03-18 20 views
6

Nếu chúng tôi có một map <int, vector<int> > được di chuyển khi cây màu đỏ đen của bản đồ thay đổi hoặc nó lưu trữ con trỏ đến vector s hoặc một cái gì đó tương tự và không di chuyển chúng (khác làm việc với bản đồ sẽ không là O (lg n) nữa ví dụ như nếu chúng ta push_back yếu tố để một số vector s)Phần thứ hai của bản đồ là <..,..> có ổn định không?

Trả lời

9

Xem cái này: std::map, pointer to map key value, is this possible?

các thứ hai câu trả lời đầu:

Mục 23.1.2 # 8 (kết hợp con yêu cầu tainer):

"Thành viên chèn sẽ không ảnh hưởng đến tính hợp lệ của trình lặp và tham chiếu đến vùng chứa và thành viên xóa sẽ chỉ vô hiệu hóa vòng lặp và tham chiếu đến phần tử đã xóa."

Vì vậy, lưu trữ con trỏ tới thành viên dữ liệu của phần tử bản đồ được đảm bảo hợp lệ, trừ khi bạn xóa yếu tố.

Vì vậy, nếu tham chiếu được giữ nguyên, dữ liệu không thể được sao chép vào một phần khác của bộ nhớ. Và nếu đúng như vậy, tôi không thấy điểm nào trong việc thực hiện bất kỳ bản sao nào cả ...

+0

Điều này không giải quyết được câu hỏi cốt lõi: Bản đồ 'std :: map' có được phép cho các phần tử _move_ không? –

+0

Nếu một yếu tố đã được di chuyển, một con trỏ/tham chiếu đến nó sẽ bị vô hiệu (tôi đang nói về con trỏ đồng bằng, không phải vòng lặp). Đó là lý do tại sao - không - nó không được phép di chuyển các phần tử. ... tốt, trong lý thuyết một số thực hiện có thể sao chép các đối tượng một nơi nào đó và sau đó di chuyển trở lại vị trí cũ, nhưng đó sẽ là hơi lạ. – CygnusX1

+0

Mặc dù không có yêu cầu nào như vậy được tạo ra từ 'xóa'. –

1

Không, các vectơ sẽ không được di chuyển xung quanh. Các thao tác của cây chỉ sắp xếp lại con trỏ giữa các nút. Chúng không di chuyển các nút hoặc nội dung của chúng trong bộ nhớ.

1

Tôi tin rằng C++ 03 không đảm bảo tính ổn định của dữ liệu trong bộ nhớ và đây sẽ là chi tiết triển khai (và thực sự không phải thứ bạn có thể giả định một cách an toàn mà không kiểm tra).

Lưu ý rằng việc bảo tồn lặp vào bản đồ và vị trí của vector thực tế trong bộ nhớ là điều hoàn toàn khác nhau. Tính hợp lệ của các trình vòng lặp được xác định rõ ràng (cả khi chúng hợp lệ và khi chúng không) trong đặc tả C++, nhưng hành vi bên trong thực tế của cây không phải là.

Điều đó nói rằng, bất kỳ trình biên dịch tốt nào (cho bản phát hành/bật tối ưu hóa) sẽ tối ưu hóa việc triển khai để không thực sự sao chép vectơ khi nó được di chuyển xung quanh cây và triển khai C++ 11 của std::map sẽ sử dụng ngữ nghĩa di chuyển để đảm bảo hành vi đó.

Điều bạn không thể giả định là các con trỏ chỉ nội bộ được di chuyển.

+1

'std :: map ' bắt buộc phải là một thùng chứa dựa trên nút trong tất cả các phiên bản của tiêu chuẩn, tức làcác nút không bị xóa khỏi bản đồ được lưu trong bộ nhớ: không phải các trình vòng lặp hay các con trỏ tới các phần tử bản đồ sẽ bị vô hiệu hóa cho đến khi nút bị xóa hoặc bản đồ bị hủy. –

+0

Nhưng nó cũng bảo tồn tài liệu tham khảo (đồng bằng con trỏ), không chỉ lặp. Điều này cho phép bạn tranh luận về bộ nhớ. Trừ khi có một số ảo hóa địa chỉ bộ nhớ lạ ... – CygnusX1

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