STL - erasing from a set

A

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());

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",
deleting a range should be a valid operation.

Regards,
Andrey
 
V

Victor Bazarov

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());

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",
deleting a range should be a valid operation.

A collection can only delete a range from *itself*. It's silly to try
to ask set_a to delete a range in set2_a.

V
 
A

A B

OK, thanks... I didn't realize that.
Which approach would be appropriate then? "set_difference" perhaps?
But it requires that the new set contain some elements already,
doesn't it? It wouldn't let you insert new elements?
 
J

Jorgen Grahn

OK, thanks... I didn't realize that.
Which approach would be appropriate then? "set_difference" perhaps?

You mean std::set_difference, I guess.
But it requires that the new set contain some elements already,
doesn't it? It wouldn't let you insert new elements?

Yes it would, with some help.

Read the documentation (the SGI STL manual for example), and especially
the code examples for std::set_difference, and the
std::back_insert_iterator documentation.

/Jorgen
 
A

A B

You mean std::set_difference, I guess.


Yes it would, with some help.

Read the documentation (the SGI STL manual for example), and especially
the code examples for std::set_difference, and the
std::back_insert_iterator documentation.

/Jorgen


I am aware of the insert iterator. However, the problem is that
std::set doesn't support the "push_back" interface that it requires.
So, when I tried this code:

set<A*> diff;
std::back_insert_iterator< set<A*> > it(diff);
set_difference(set_a.begin(), set_a.end(), set2_a.begin(),
set2_a.end(), it);

I got (under GCC) the expected error message

/usr/include/c++/4.4/bits/stl_iterator.h:417: error: ‘class
std::set<A*, std::less<A*>, std::allocator<A*> >’ has no member named
‘push_back’

Is there an agreed standard (that is, short and efficient) procedure
for generating a set difference in a new set?
 
J

Juha Nieminen

A B said:
I am aware of the insert iterator. However, the problem is that
std::set doesn't support the "push_back" interface that it requires.
So, when I tried this code:

set<A*> diff;
std::back_insert_iterator< set<A*> > it(diff);

Why do you want to use std::back_insert_iterator instead of
std::insert_iterator?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top