2011-12-25 38 views
12

tôi gặp sự cố khi tôi muốn thay đổi phần tử của bộ bằng cách sử dụng trình lặp. Mã đơn giản này có thể giải thích những gì tôi muốn làm.thay đổi phần tử bằng trình vòng lặp

set<int> s; 
    s.insert(12); 

    set<int>::iterator it = s.begin(); 
    *it = 4; // error C3892: 'it' : you cannot assign to a variable that is const 

Tại sao tôi không thể thay đổi giá trị được chỉ định bởi trình lặp thông thường, không phải const_iterator?

Trong trình lặp mã của tôi được trả về theo bộ :: find(). Có lẽ là cách tốt hơn để chọn yếu tố cụ thể từ bộ và thay đổi anh ta.

Trả lời

12

Tập hợp là một thùng chứa có thứ tự (đặc biệt chúng được thực hiện dưới dạng cây tìm kiếm nhị phân cân bằng). Nếu bạn có thể thay đổi giá trị của phần tử thông qua trình lặp, thứ tự bất biến sẽ bị hỏng. Tùy thuộc vào những gì bạn đang cố gắng để đạt được bạn có thể tốt hơn với một container khác nhau hoặc có được giá trị, loại bỏ các phần tử và chèn một phần tử mới vào tập hợp.

+3

+1: Mặc dù điều này để lại câu hỏi: tại sao 'bắt đầu' trả về trình lặp không phải là 'const'? –

+0

Trả về một trình lặp bình thường là khó hiểu, nhưng bây giờ ít nhất là hiểu tại sao tôi nhận được lỗi này. Cảm ơn rất nhiều. – Scypi

+0

@OliCharlesworth, Scypi: Điều này phức tạp hơn một chút, trình lặp không phải là 'const_iterator', mà là một trình lặp * mutable *. Đó là 'Phím' có thể được lập chỉ mục một phím * không thay đổi *. §23.2.4p5 * "[...] Các khóa trong một thùng chứa liên kết là không thay đổi." * Về lý do tại sao chúng cung cấp không const 'begin()' và kết thúc (thay vì 'const_iterator' luôn luôn), tôi đoán là nó là được thực hiện để giữ cho các giao diện container càng thống nhất càng tốt. Cụ thể §23.2.4p6 nói rằng trong trường hợp này các kiểu 'iterator' và' const_iterator' * có thể * giống nhau, và gợi ý sử dụng 'const_iterator' luôn để tránh vi phạm ODR. –

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