Tôi có một tập hợp các phần tử trong một std :: vector được sắp xếp theo thứ tự giảm dần bắt đầu từ phần tử đầu tiên. Tôi phải sử dụng một vector vì tôi cần phải có các phần tử trong một bộ nhớ liền kề. Và tôi có một bộ sưu tập chứa nhiều trường hợp vectơ với các đặc tính được mô tả (luôn được sắp xếp theo thứ tự giảm dần). Bây giờ, đôi khi, khi tôi phát hiện ra rằng tôi có quá nhiều phần tử trong bộ sưu tập lớn hơn (bộ chứa các vectơ này), tôi loại bỏ các phần tử nhỏ nhất khỏi các vectơ này theo cách tương tự với mã giả này:vector :: xóa và đảo ngược_iterator
grand_collection: collection that holds these vectors
T: type argument of my vector
C: the type that is a member of T, that participates in the < comparison (this is what sorts data before they hit any of the vectors).
std::map<C, std::pair<T::const_reverse_iterator, std::vector<T>&>> what_to_delete;
iterate(it = grand_collection.begin() -> grand_collection.end())
{
iterate(vect_rit = it->rbegin() -> it->rend())
{
// ...
what_to_delete <- (vect_rit->C, pair(vect_rit, *it))
if (what_to_delete.size() > threshold)
what_to_delete.erase(what_to_delete.begin());
// ...
}
}
Bây giờ, sau khi chạy mã này, trong what_to_delete
Tôi có một tập hợp các trình vòng lặp trỏ đến vectơ gốc mà tôi muốn xóa khỏi các vectơ này (tổng giá trị nhỏ nhất). Hãy nhớ rằng, các vectơ gốc được sắp xếp trước khi chúng đạt mã này, có nghĩa là đối với bất kỳ what_to_delete[0 - n]
không có cách nào mà một trình lặp trên vị trí n - m
sẽ trỏ đến một phần tử từ đầu của cùng một véc tơ hơn n
, trong đó m > 0
.
Khi xóa các phần tử khỏi vectơ gốc, tôi phải chuyển đổi trình đảo ngược thành bộ lặp. Để làm điều này, tôi dựa trên C++ của 11 §24.4.1/1:
Mối quan hệ giữa reverse_iterator và iterator là & * (reverse_iterator (i)) == & * (i- 1)
có nghĩa là để xóa một vect_rit
, tôi sử dụng:
vector.erase(--vect_rit.base());
Bây giờ, theo C++ 11 tiêu chuẩn §23.3.6.5/3
:
xóa vòng lặp (vị trí trình giữ nguyên); Hiệu ứng: Vô hiệu hóa trình lặp và tham chiếu tại hoặc sau thời điểm xóa.
Điều này hoạt động như thế nào với trình đảo ngược? Là reverse_iterators nội bộ thực hiện với một tham chiếu đến một bắt đầu thực sự của vector (vector[0]
) và chuyển đổi vect_rit đó để một iterator cổ điển để sau đó tẩy xoá sẽ được an toàn? Hoặc không reverse_iterator sử dụng rbegin() (là (vector[vector.size()]
) như là một điểm tham chiếu và xóa bất cứ điều gì đó là xa hơn từ 0-chỉ số của vector sẽ vẫn làm mất hiệu lực iterator đảo ngược của tôi?
Edit:
Hình như reverse_iterator sử dụng rbegin() là điểm tham chiếu của nó. Việc xóa các phần tử theo cách tôi mô tả đã cho tôi lỗi về một trình lặp không thể tránh khỏi sau khi phần tử đầu tiên bị xóa. Trong khi khi lưu trữ các trình vòng lặp cổ điển (chuyển đổi thành const_iterator
) trong khi chèn vào what_to_delete
hoạt động chính xác.
Bây giờ, để tham khảo trong tương lai, tiêu chuẩn có quy định cụ thể những gì cần được coi là điểm tham chiếu trong trường hợp của reverse_iterator truy cập ngẫu nhiên không? Hoặc đây là một chi tiết thực hiện?
Cảm ơn!
Câu hỏi về thư của tiêu chuẩn hoặc về triển khai phổ biến? – Managu
@Managu - Cả hai. –
Theo như tôi hiểu, bạn không có/muốn sử dụng một 'reverse_iterator' ở đây. 'std :: vector' có các trình vòng lặp truy cập ngẫu nhiên có nghĩa là bạn chỉ có thể sử dụng một' iterator' thông thường bắt đầu từ '.end()' và di chuyển nó về phía sau. Bằng cách này, bạn không phải làm nhiều phép thuật để sử dụng '.erase()'. –