ค่าคีย์ขององค์ประกอบใน a std::setนั้นconstมีเหตุผลที่ดี std::setการปรับเปลี่ยนพวกเขาอาจทำลายการสั่งซื้อซึ่งเป็นสิ่งจำเป็นสำหรับ
ดังนั้นการแก้ปัญหาคือการลบ iterator *it - subและใส่ใหม่ด้วยกุญแจ โปรดทราบว่าstd::set::erase()จะส่งคืนตัววนซ้ำใหม่ซึ่งจะต้องใช้ในกรณีของคุณเพื่อให้ห่วงขณะทำงานอย่างถูกต้อง
#include<iostream>
#include<set>
template <typename T>
std::ostream& operator<<(std::ostream &out, const std::set<T> &values)
{
const char *sep = "{ ";
for (const T &value : values) { out << sep << value; sep = ", "; }
return out << " }";
}
int main()
{
std::set<int> test{ 11, 12, 13, 14, 15 };
std::cout << "test: " << test << '\n';
const int sub = 10;
std::set<int>::iterator iter = test.begin();
while (iter != test.end()) {
const int value = *iter;
iter = test.erase(iter);
test.insert(value - sub);
}
std::cout << "test: " << test << '\n';
}
เอาท์พุท:
test: { 11, 12, 13, 14, 15 }
test: { 1, 2, 3, 4, 5 }
การสาธิตสดบน coliru
การเปลี่ยนแปลงในstd::setขณะที่วนซ้ำมันไม่ใช่ปัญหาโดยทั่วไป แต่อาจทำให้เกิดปัญหาเล็กน้อย
ความจริงที่สำคัญที่สุดคือทุกคนที่ใช้ตัววนซ้ำต้องไม่อยู่ในสภาพสมบูรณ์หรือไม่สามารถใช้งานได้อีกต่อไป (นั่นเป็นสาเหตุที่ทำให้ตัววนซ้ำปัจจุบันขององค์ประกอบการลบถูกกำหนดด้วยค่าส่งคืนstd::set::erase()ซึ่งเป็นตัววนซ้ำสมบูรณ์หรือจุดสิ้นสุดของชุด)
แน่นอนว่าสามารถใส่องค์ประกอบต่าง ๆ ไว้ข้างหลังตัววนซ้ำปัจจุบันได้ แม้ว่านี่จะไม่ใช่ปัญหาที่เกี่ยวข้องกับstd::setมัน แต่มันก็อาจทำให้ลูปของตัวอย่างข้างต้นของฉัน
เพื่อแสดงให้เห็นว่าฉันเปลี่ยนตัวอย่างข้างต้นเล็กน้อย โปรดทราบว่าฉันได้เพิ่มตัวนับเพิ่มเติมเพื่อให้การยกเลิกลูป:
#include<iostream>
#include<set>
template <typename T>
std::ostream& operator<<(std::ostream &out, const std::set<T> &values)
{
const char *sep = "{ ";
for (const T &value : values) { out << sep << value; sep = ", "; }
return out << " }";
}
int main()
{
std::set<int> test{ 11, 12, 13, 14, 15 };
std::cout << "test: " << test << '\n';
const int add = 10;
std::set<int>::iterator iter = test.begin();
int n = 7;
while (iter != test.end()) {
if (n-- > 0) {
const int value = *iter;
iter = test.erase(iter);
test.insert(value + add);
} else ++iter;
}
std::cout << "test: " << test << '\n';
}
เอาท์พุท:
test: { 11, 12, 13, 14, 15 }
test: { 23, 24, 25, 31, 32 }
การสาธิตสดบน coliru