2013-04-30 25 views
7

Theo tham chiếu C++, thiết lập :: chèn là nghĩa vụ phải trả về cặp nơi mà trình vòng lặp trỏ tới phần tử mới được chèn vào hoặc phần tử hiện có nếu tồn tại.return iterator từ std :: set :: insert() là const?

Nhưng tôi đang gặp một vấn đề gán cho iterator, như ví dụ đơn giản này cho thấy:

int main() { 
    set<int> set; 
    *set.insert(5).first = 5; 
    return 0; 
} 

Tôi đã thử G ++ và Clang và không hoạt động.

set.cc:7:24: error: read-only variable is not assignable 
    *set.insert(5).first = 5; 
    ~~~~~~~~~~~~~~~~~~~~^

Tôi không thể tìm thấy bất kỳ điều gì trong tài liệu chỉ ra rằng trình vòng lặp nên ưu tiên đối tượng const và không có chữ ký nào cho biết điều này. Ai đó có thể giúp tôi hiểu tại sao điều này không hiệu quả?

Trả lời

13

Đối với std::set, cả hai loại liên kết iteratorconst_iterator là các trình lặp hai chiều không đổi. Lý do là vì std::set được đặt hàng. Nếu bạn đã sửa đổi một phần tử của tập hợp mặc dù một trình lặp, bạn sẽ phá vỡ thứ tự đó.

Xem xét một std::set với các yếu tố đã đặt hàng {1, 4, 8}. Nếu sau đó bạn đã thực hiện một cái gì đó như *set.insert(5).first = 10; (nếu nó được cho phép), trước tiên 5 sẽ được chèn để lấy {1, 4, 5, 8} và sau đó phần tử được chèn sẽ được đặt thành 10 để nhận {1, 4, 10, 8}. Biến thể thứ tự đã bị phá vỡ.

Vì bạn đang chèn 5 với insert(5), không có lý do gì để bỏ qua phép lặp và gán 5 cho nó.

+0

Duh. Tôi nên nghĩ về điều này. Cảm ơn. Trong ví dụ thực sự của tôi, nó không phải là một int, là một đối tượng phức tạp hơn mà tôi muốn thay đổi một số trạng thái trên. – drwowe

4

Bạn không thể sửa đổi thành viên của nhóm. Đó là một container theo thứ tự. Các trình vòng lặp của nó không thể gán được.

3

Trong C++ 11, đặt trình vòng lặp tham chiếu đến các loại const (xem set reference). Nếu bạn nghĩ về nó, nó có ý nghĩa, như một tập hợp lưu trữ các phần tử của nó được sắp xếp, và đơn giản là việc thay đổi một phần tử nhất định sẽ rất có khả năng vi phạm các ràng buộc đặt hàng.

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