Re: STL - erasing from a set
Am 17.11.2010 22:03, schrieb A B:
Hello,
I am trying to do a "set difference" operation, to trying to take some
elements (objects) out of a set. I wrote a small sample program to
test it.
--------------------------------------
#include<iostream>
#include<cstdlib>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
class A {
public:
A();
~A();
};
A::A() {
cout<< "Constructing A\n";
}
A::~A() {
cout<< "Destructing A\n";
}
int main() {
A a;
A a2;
A a3;
A* ptr_a =&a;
A* ptr_a2 =&a2;
A* ptr_a3 =&a3;
set<A*> set_a;
set_a.insert(ptr_a); set_a.insert(ptr_a2); set_a.insert(ptr_a3);
set<A*> set2_a;
set2_a.insert(ptr_a); set2_a.insert(ptr_a2);
cout<< "Before erase\n";
set_a.erase(set2_a.begin(), set2_a.end());
This is the line of error, see below.
cout<< "End of main\n";
return 0;
}
--------------------------------------
The idea is that set_a should contain only ptr_a3 after the "erase"
operation. Instead, what I get is:
Constructing A
Constructing A
Constructing A
Before erase
Segmentation fault
What am I missing? According to the STL documentation for "set",
applying "erase" to an iterator-delimited range should be a valid
operation.
The incorrect assumption here is that you could provide *any* range as
argument of erase. This is not the case, it must be an iterator range of
the *same* container. This becomes clear, if you track the definition of
q1 and q2 from Table 69?"Associative container requirements (in addition
to container)" from the C++03 standard for the signature a.erase(q1,q2):
"In Table 69, X is an associative container class, a is a value of X
[..], [q1, q2) is a valid range in a, [..]"
Arguably one could also interpret the signature (without the explanatory
text) to erase all elements with the same *key* as the provided
sequence. A simple way to realize what you want is to take advantage of
the erase overload of set that takes a *key*:
for (set<A*>::const_iterator it = set2_a.begin(), end = set2_a.end(); it
!= end; ++it) {
set_a.erase(*it);
}
In C++0x you *really* want to take advantage of the new for-range loop:
for (const auto& key : set2_a) {
set_a.erase(key);
}
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]