473,513 Members | 2,749 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

STL function REMOVE doesn't work

Hello!

I have some problem with STL function remove

I have two classes called Handle which is a template class and Integer which
is not a template class. The Integer class is just a wrapper class for a
primitive int with some methods. I don't show the Integer class because it
will not add any information to my problem. Main is using some STL function

Now to my problem.
If I do this sequence in main first create two Handle object myh1 and myh2.
Then I use push_front to first push in myh1 and then myh2 into the list
Then I use the STL function for_each in this way
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would write 2 and then 1 because I pushed_front the
Handle myh1 and then myh2

This function for_each will write out the entire list by calling the
function operator defined as
void operator()(Handle& temp) //Funktionsanropsoperator
{ cout << *temp.body << endl; }
for each Handle in the list. The function operator will write the primitive
ints because the wrapper class Integer has a type conversion operator that
convert from the class Integer to an int.

When I want to remove a Handle from the list I use the STL function remove
in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for
Handle would be called when I do the remove but it doesn't. If I want to
write out the list after I have done the remove I use the for_each again in
this way.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would now write out 1 and then 1. It should only have
written 1 because the 2 should have been removed. The other strange thing is
that the removed 3 has been changed to 1 in some strange way that I don't
understand.

Have you any suggestion ?

//Tony
#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
remove(myList1.begin(), myList1.end(), myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
}

#include "integer.h"
#include <iostream>
using namespace std;

template<class T>
class Handle
{
public:
Handle()
{
body = new T(0);
ref_count = new int(1);
}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

~Handle() //Destructor
{
(*ref_count)--;
if (!*ref_count)
deleteAll();
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << * temp.body << endl; }
private:
T* body;
int* ref_count;

void deleteAll()
{
delete body;
body = NULL;
delete ref_count;
ref_count = NULL;
}
};
Jul 23 '05 #1
11 3056

Tony Johansson wrote:
Hello!

I have some problem with STL function remove

I have two classes called Handle which is a template class and Integer which is not a template class. The Integer class is just a wrapper class for a primitive int with some methods. I don't show the Integer class because it will not add any information to my problem. Main is using some STL function
Now to my problem.
If I do this sequence in main first create two Handle object myh1 and myh2. Then I use push_front to first push in myh1 and then myh2 into the list Then I use the STL function for_each in this way
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would write 2 and then 1 because I pushed_front the Handle myh1 and then myh2

This function for_each will write out the entire list by calling the
function operator defined as
void operator()(Handle& temp) //Funktionsanropsoperator
{ cout << *temp.body << endl; }
for each Handle in the list. The function operator will write the primitive ints because the wrapper class Integer has a type conversion operator that convert from the class Integer to an int.

When I want to remove a Handle from the list I use the STL function remove in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for Handle would be called when I do the remove but it doesn't. If I want to write out the list after I have done the remove I use the for_each again in this way.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would now write out 1 and then 1. It should only have written 1 because the 2 should have been removed. The other strange thing is that the removed 3 has been changed to 1 in some strange way that I don't understand.

Have you any suggestion ?

//Tony
#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
remove(myList1.begin(), myList1.end(), myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
}

#include "integer.h"
#include <iostream>
using namespace std;

template<class T>
class Handle
{
public:
Handle()
{
body = new T(0);
ref_count = new int(1);
}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

~Handle() //Destructor
{
(*ref_count)--;
if (!*ref_count)
deleteAll();
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << * temp.body << endl; }
private:
T* body;
int* ref_count;

void deleteAll()
{
delete body;
body = NULL;
delete ref_count;
ref_count = NULL;
}
};


Hi,

Please post the Integer class details...

-vs_p...

Jul 23 '05 #2

"Achintya" <vs********@yahoo.com> skrev i meddelandet
news:11*********************@f14g2000cwb.googlegro ups.com...

Tony Johansson wrote:
Hello!

I have some problem with STL function remove

I have two classes called Handle which is a template class and Integer which
is not a template class. The Integer class is just a wrapper class

for a
primitive int with some methods. I don't show the Integer class

because it
will not add any information to my problem. Main is using some STL

function

Now to my problem.
If I do this sequence in main first create two Handle object myh1 and

myh2.
Then I use push_front to first push in myh1 and then myh2 into the

list
Then I use the STL function for_each in this way
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would write 2 and then 1 because I pushed_front

the
Handle myh1 and then myh2

This function for_each will write out the entire list by calling the
function operator defined as
void operator()(Handle& temp) //Funktionsanropsoperator
{ cout << *temp.body << endl; }
for each Handle in the list. The function operator will write the

primitive
ints because the wrapper class Integer has a type conversion operator

that
convert from the class Integer to an int.

When I want to remove a Handle from the list I use the STL function

remove
in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor

for
Handle would be called when I do the remove but it doesn't. If I want

to
write out the list after I have done the remove I use the for_each

again in
this way.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would now write out 1 and then 1. It should

only have
written 1 because the 2 should have been removed. The other strange

thing is
that the removed 3 has been changed to 1 in some strange way that I

don't
understand.

Have you any suggestion ?

//Tony
#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
remove(myList1.begin(), myList1.end(), myh2);
for_each(myList1.begin(), myList1.end(), handle_t());
}

#include "integer.h"
#include <iostream>
using namespace std;

template<class T>
class Handle
{
public:
Handle()
{
body = new T(0);
ref_count = new int(1);
}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

~Handle() //Destructor
{
(*ref_count)--;
if (!*ref_count)
deleteAll();
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << * temp.body << endl; }
private:
T* body;
int* ref_count;

void deleteAll()
{
delete body;
body = NULL;
delete ref_count;
ref_count = NULL;
}
};


Hi,

Please post the Integer class details...

-vs_p...


Hello!!

Here is the Integer class

#ifndef INTEGER_H
#define INTEGER_H
#include <iostream>
class Integer
{
public:
Integer()
{}

Integer(int value): value_(value)
{
copy_cnt = new int(0);
std::cout << "Creating original:"<< value << std::endl;
};

Integer(const Integer& src): value_(src.value_), copy_cnt(src.copy_cnt)
{
(*copy_cnt) += 1;
std::cout << "Creating copy:"<< *copy_cnt << " of:" << value_ <<
std::endl;
};

virtual ~Integer()
{
if(*copy_cnt == 0)
{
std::cout << "Deleting last: "<< value_ << std::endl;
delete copy_cnt;
}
else
{
(*copy_cnt) -= 1;
std::cout << "Deleting: "<< value_ << "\t\t "<< *copy_cnt << " copies
are left" << std::endl;
}
};

const Integer& operator=(const Integer& src)
{
this->value_ = src.value_;
if(*copy_cnt == 0)
{
delete copy_cnt;
}
else
{
(*copy_cnt) -= 1;
}
copy_cnt = src.copy_cnt;
(*copy_cnt) += 1;
return *this;
}
bool operator==(const Integer& src) const
{ return this->value_ == src.value_; }

bool operator!=(const Integer& src) const
{ return this->value_ != src.value_; }

operator int() const
{ return this->value_; }

void setValue(int value)
{
this->value_ = value;
if(*copy_cnt > 0)
{
*copy_cnt -= 1;
copy_cnt = new int;
*copy_cnt = 0;
}
}

private:
int value_;
int *copy_cnt;
};
#endif

Jul 23 '05 #3
Tony Johansson wrote:
Hello!

[snip]

When I want to remove a Handle from the list I use the STL function remove
in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for
Handle would be called when I do the remove but it doesn't. If I want to
Because 'remove' doesn't destory any iterator. If you print the size of
the list 'myList1', you will see the size is still same i.e. 2. remove
returns the iterator of 'newLast', where [myList1.begin(), newLast)
contains no elements equal to myh2.

If you want to 'actually' remove the myh2 from myList1, you need to call

myList1.erase(remove(myList1.begin(), myList1.end(), myh2),
myList1.end());

write out the list after I have done the remove I use the for_each again in
this way.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would now write out 1 and then 1. It should only have
written 1 because the 2 should have been removed. The other strange thing is
that the removed 3 has been changed to 1 in some strange way that I don't
understand.


After remove, dereferencing the iterators within range [newLast,
myList1.end()) are legal, but the elements they point to are
unspecified.

Krishanu

--
"Automatically translated code seldom looks nice and is usually not
meant to be read by humans..."
--Jens Thoms Toerring

Jul 23 '05 #4

Krishanu Debnath wrote:
Tony Johansson wrote:
Hello!

[snip]

When I want to remove a Handle from the list I use the STL function remove in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for Handle would be called when I do the remove but it doesn't. If I want to
Because 'remove' doesn't destory any iterator. If you print the size of the list 'myList1', you will see the size is still same i.e. 2. remove returns the iterator of 'newLast', where [myList1.begin(), newLast)
contains no elements equal to myh2.

If you want to 'actually' remove the myh2 from myList1, you need to call
myList1.erase(remove(myList1.begin(), myList1.end(), myh2),
myList1.end());

write out the list after I have done the remove I use the for_each

again in this way.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator would now write out 1 and then 1. It should only have written 1 because the 2 should have been removed. The other strange thing is that the removed 3 has been changed to 1 in some strange way that I don't understand.


After remove, dereferencing the iterators within range [newLast,
myList1.end()) are legal, but the elements they point to are
unspecified.

Krishanu

--
"Automatically translated code seldom looks nice and is usually not
meant to be read by humans..."
--Jens Thoms Toerring


Hi,

Yup,...in other words 'remove' simply moves the selected elements to
the end of the sequence and returns an iterator to the first 'removed'
element.

-vs_p...

Jul 23 '05 #5
On Tue, 17 May 2005 07:11:08 GMT, "Tony Johansson"
<jo*****************@telia.com> wrote:
When I want to remove a Handle from the list I use the STL function remove
in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for
Handle would be called when I do the remove but it doesn't.


The name of this function is confusing -- it doesn't remove anything
it just reorder the collection. You can think about it like the
partition in reverse.

Partition moves given elements to the front of the collection, remove
-- to the back.

1 2 3 1

when you apply the remove function with "1" you will get:

2 3 1 1

And now you can apply the erase function. Good STL guide is very
helpful, try Josuttis, it's category-killer.

have a nice day
bye
--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny tłumacz (wczesna wersja rozwojowa) angielsko-polski
Jul 23 '05 #6
On 17 May 2005 00:40:18 -0700, "Achintya" <vs********@yahoo.com>
wrote:
Please post the Integer class details...


And you have to quote the whole message just to add those witty words?

--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny tłumacz (wczesna wersja rozwojowa) angielsko-polski
Jul 23 '05 #7
Achintya wrote:
Yup,...in other words 'remove' simply moves the selected elements to
the end of the sequence and returns an iterator to the first 'removed' element.


No, 'remove' may also overwrite and duplicate elements (see e.g.
Stroustrup). It's a good example of a bad interface design.

R.C.

Jul 23 '05 #8
In message <73********************************@4ax.com>, Maciej
Pilichowski <ba***@SKASUJTOpoczta.FM> writes
On Tue, 17 May 2005 07:11:08 GMT, "Tony Johansson"
<jo*****************@telia.com> wrote:
When I want to remove a Handle from the list I use the STL function remove
in this way
remove(myList1.begin(), myList1.end(), myh2);
Here I remove the Handle named myh2.

But now to the very strange thing. I would expect that the destructor for
Handle would be called when I do the remove but it doesn't.
The name of this function is confusing -- it doesn't remove anything
it just reorder the collection. You can think about it like the
partition in reverse.

Partition moves given elements to the front of the collection, remove
-- to the back.


Not quite. After calling partition() you have exactly the same elements,
in a different order. All elements are preserved.

After remove(), the back of the sequence contains garbage - a mixture of
unwanted elements and _copies_ of the wanted ones. There's no guarantee
that the unwanted elements are preserved.
1 2 3 1

when you apply the remove function with "1" you will get:

2 3 1 1
I suspect you'll actually get 2 3 3 1

And now you can apply the erase function. Good STL guide is very
helpful, try Josuttis, it's category-killer.

have a nice day
bye


--
Richard Herring
Jul 23 '05 #9
Tony Johansson wrote:
Hello!

I have some problem with STL function remove


This is discussed in Meyer's Effective STL and also in footnote [1] of
http://www.sgi.com/tech/stl/remove.html

Note in particular the erase-remove idiom which may be what you're
looking for.

Mark
Jul 23 '05 #10
On Tue, 17 May 2005 10:07:37 +0100, Richard Herring <ju**@[127.0.0.1]>
wrote:
After remove(), the back of the sequence contains garbage - a mixture of
unwanted elements and _copies_ of the wanted ones. There's no guarantee
that the unwanted elements are preserved.


Thank you for pointing that out -- I tried too hard to make an
analogy, sorry ;-)

Kind regards,

--
Maciej "MACiAS" Pilichowski http://bantu.fm.interia.pl/

M A R G O T --> http://www.margot.cad.pl/
automatyczny tłumacz (wczesna wersja rozwojowa) angielsko-polski
Jul 23 '05 #11

Rapscallion wrote:
Achintya wrote:
Yup,...in other words 'remove' simply moves the selected elements to the end of the sequence and returns an iterator to the first

'removed'
element.


No, 'remove' may also overwrite and duplicate elements (see e.g.
Stroustrup). It's a good example of a bad interface design.


It's a good example of generic design. The domain on which
the STL works is ranges, not containers. You simply cannot
remove elements from a char[20]. However, you can create
a subrange within the char[20] that has the desired property. By
definition, you're not interested in the
remainder, or you'd use remove_copy/copy_if

HTH,
Michiel Salters

Jul 23 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
4935
by: Penn Markham | last post by:
Hello all, I am writing a script where I need to use the system() function to call htpasswd. I can do this just fine on the command line...works great (see attached file, test.php). When my...
6
3455
by: Colin Steadman | last post by:
I have created a function to kill all session variables that aren't in a safe list. This is the function - Sub PurgeSessionVariables For Each Item In Session.Contents Select Case Trim(Item)...
6
6070
by: Hoschi-Ingo | last post by:
Hello NG, I want to write a generic function to validate data in input items. For this I want to pass a refernce to the object which calls this function to read out the and modify it if...
3
3584
by: Eric Theil | last post by:
I'm at my wit's end with this one. Within an xsl:if test, I'm not able to get 2 variables to properly evaluate if one of them is wrapped within a string function. <!-- This works --> <xsl:if...
4
2844
by: Dalan | last post by:
Perhaps someone can share information on the methods to use to effect the automation process of creating the property to set the AllowBypassKey function. I was directed to:...
7
2597
by: Kieran Simkin | last post by:
Hi all, I'm having some trouble with a linked list function and was wondering if anyone could shed any light on it. Basically I have a singly-linked list which stores pid numbers of a process's...
6
12261
by: grist2mill | last post by:
I want to create a standard tool bar that appears on all pages that is a control. The toolbar has a button 'New'. What I wolud like when the user clicks on 'New' depends on the page they are on. I...
89
5949
by: Cuthbert | last post by:
After compiling the source code with gcc v.4.1.1, I got a warning message: "/tmp/ccixzSIL.o: In function 'main';ex.c: (.text+0x9a): warning: the 'gets' function is dangerous and should not be...
11
3741
by: kennthompson | last post by:
Trouble passing mysql table name in php. If I use an existing table name already defined everything works fine as the following script illustrates. <?php function fms_get_info() { $result =...
0
7259
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7158
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7380
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7535
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7523
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5683
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5085
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3221
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
455
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.