한 세트의 요소가 반복자를 허용하는 erase 메소드를 사용하여 다른 세트에서 삭제 될 수 있다는 것을 알게되었습니다. 왜 이런 일이 일어날 지 설명 할 수 없으며 이것이 정상적인 행동인지 아닌지 알고 싶습니다. 난 논리적 인 이유를 들어, 두 개의 STL 세트에서 분리 된 개체 집합 (즉, 그들은 개별 세트입니다)가다른 세트에서 erase (iterator)를 호출하여 한 세트에서 요소를 삭제합니다. 이것은 정상적인 행동입니까?
:
그래서, 장면을 설정할 수 있습니다.
std::set<Obj> set_a;
std::set<Obj> set_b;
set_a 내가 원하는 개체를 포함합니다. 이 객체가 set_a에서 발견되지 않으면 빈 객체가 만들어져 set_b에 삽입됩니다. 그런 다음 원하는 객체에 대해 몇 가지 계산을 수행하고 특정 조건이 충족되면 삭제합니다.
std::set<Obj>::iterator it = set_a.find(o);
std::set<Obj>::iterator end = set_a.end();
if (it == end) {
it = set_b.lower_bound();
end = set_b.end();
if (it == end || *it != o) {
it = set_b.insert(it, o);
}
}
// do calculations with it
if (/*condition is met*/) {
// erase it
}
그래서 나는이 개체를 삭제 얼마나 궁금 해서요. 필자는 반복기를 사용하므로 직접 사용하여 삭제할 생각을했습니다. 그러나 반복자를 지우개를 사용하여 다른 세트의 객체를 "가리키는"경우에는 어떤 일이 발생합니까? 내가 사용하는 문서 (http://www.cplusplus.com/reference/stl/set/erase/)에는 아무 것도 없으므로 다음 테스트를 수행했습니다. 다음과 같은 종료에
#include <iostream>
#include <iterator>
#include <algorithm>
#include <set>
#include <sstream>
// streams
using std::cout;
using std::ostream_iterator;
using std::ostringstream;
// data structures
using std::set;
// algorithms
using std::copy;
int main() {
set<int> s, s2;
s.insert(1);
s.insert(2);
s.insert(4);
cout << "Initial set\n";
// print set elements
copy(s.begin(), s.end(), ostream_iterator<int> (cout, " "));
cout << "\n";
set<int>::iterator s_it = s.lower_bound(3);
if (s_it == s.end() || *s_it != 3) {
s_it = s.insert(s_it, 3);
}
cout << "Set after insertion\n";
// print set elements
copy(s.begin(), s.end(), ostream_iterator<int> (cout, " "));
cout << "\n";
// erase element from another set
s2.erase(s_it);
cout << "Set after erasure\n";
// print set elements
copy(s.begin(), s.end(), ostream_iterator<int> (cout, " "));
cout << "\n";
return 0;
}
이 테스트 결과 :
Initial set 1 2 4 Set after insertion 1 2 3 4 Set after erasure 1 2 4
나는 s의 요소가 (S2)에서 메소드를 호출에 의해 삭제 될 수 있음을 매우 이상한 발견, 그래서 나는 내 프로그램을 실행 valgrind. 오류가 없습니다. 어떤 세트에 요소가 들어 있는지 확인할 필요가 없기 때문에 실제로이 동작의 이점을 얻을 것이라고 생각합니다. 그러나 이것이 정상적인 동작인지 아닌지 궁금합니다.
감사합니다!
내가 결론을 내릴지 확실하지 않습니다. 요소를 s에 넣고 s에서 요소를 가리키는 반복자를 사용하여 요소를 삭제합니다. s2는 정말로 아무 것도하지 않았습니다. –
@Anon, s에서 반복자를 사용하여 s2.erase()를 호출하면 s를 제공하는 것이 좋습니다. s2는 동일한 유형입니까? –
@ 토니 : 나는 그것을 말하고 있지 않다. 나는 "B의 반복자에서 A의 요소를 삭제하는 것"이 여기서 일어나지 않는다고 말하고 있습니다. –