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;
}
}; 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...
"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
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
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...
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
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
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.
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
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
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
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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...
|
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)...
|
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...
|
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...
|
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:...
| |
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...
|
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...
|
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...
|
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 =...
|
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,...
|
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...
| |
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,...
|
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...
|
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...
|
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,...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
| |
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...
| |