 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
kwijibo28 Guest
|
Posted: Wed Dec 22, 2004 8:56 am Post subject: Using remove_if with a member function |
|
|
Hi all,
Consider the following toy problem where a define a class MyInt which
is wrapper for an integer. Then I create and fill a std::vector of
those MyInt. Finally I try to remove from this vector every element
bigger than 2.
class MyInt
{
public:
MyInt() {}
MyInt(MyInt const & Input) {*this = Input}
virtual ~MyInt() {}
void operator=(MyInt const & Input){data = Input.data;}
int & GetInt() {return data;}
protected:
int data;
};
int main()
{
std::vector<MyInt> MyIntVector(5);
MyIntVector[0].GetInt() = 0;
MyIntVector[1].GetInt() = 1;
MyIntVector[2].GetInt() = 2;
MyIntVector[3].GetInt() = 3;
MyIntVector[4].GetInt() = 4;
int i;
for (i=MyIntVector.size()-1;i>=0;--i)
if (MyIntVector[i].GetInt()>2)
MyIntVector.erase(MyIntVector.begin()+i);
return 0;
}
I'm currently trying to learn the STL. I was wondering if it was
possible to rewrite this piece of code using std::remove_if? I was
considering something like this:
int main()
{
...
std::vector<MyInt>::iterator it;
it = std::remove_if(MyIntVector.begin(),MyIntVector.end(),???);
MyIntVector.erase(it,MyIntVector.end());
return 0;
}
As you can see I don't know how to write the unary predicate.
My starting point is simply this:
std::bind2nd(std::greater<int>(),2);
The way I see it this is a unary predicate taking an int as input.
How can I modify this predicate so it take an object MyInt as input
using the member function GetInt().
I've tried many variations using mem_fun() and mem_fun_ref() in vain.
My first question is simple: Is it possible to use remove_if() for my
problem?
My second question is related to the first one: If so, how?
Thanks you all for your time.
Kwijibo28
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
L.Suresh Guest
|
Posted: Thu Dec 23, 2004 3:39 pm Post subject: Re: Using remove_if with a member function |
|
|
Your code has lots of problems. You may want to look at how to write a
copy constructor. Why does your class have virtual functions? you are
not providing a convenient way to initialize your member. You will have
to provide other operators if you are trying to encapsulate an int.
You will have to be careful while erasing in a loop, because erase
might invalidate the
iterator. you have to take the iterator returned by the erase while
looping.
--lsu
#include <vector>
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
class MyInt
{
public:
MyInt(int i) : data(i) {}
MyInt(MyInt const& other) : data(other.data) {}
operator int&() {
return data;
}
private:
int data;
};
int main()
{
std::vector<MyInt> vec;
vec.push_back(0);
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout));
std::cout << std::endl;
std::vector
std::remove_if(vec.begin(),
vec.end(),
std::bind2nd(std::greater<int>(), 2));
vec.erase(iter, vec.end());
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout));
return 0;
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Paavo Helde Guest
|
Posted: Thu Dec 23, 2004 9:14 pm Post subject: Re: Using remove_if with a member function |
|
|
[email]kwijibo28 (AT) hotmail (DOT) com[/email] (kwijibo28) wrote in
news:e291e526.0412211254.6d86f576 (AT) posting (DOT) google.com:
| Quote: | Hi all,
Consider the following toy problem where a define a class MyInt which
is wrapper for an integer. Then I create and fill a std::vector of
those MyInt. Finally I try to remove from this vector every element
bigger than 2.
class MyInt
{
public:
MyInt() {}
MyInt(MyInt const & Input) {*this = Input}
virtual ~MyInt() {}
void operator=(MyInt const & Input){data = Input.data;}
int & GetInt() {return data;}
|
I'm sure you know this function nullifies the effort to put 'data' under
the 'protected' keyword.
| Quote: | protected:
int data;
};
[...]
std::vector<MyInt>::iterator it;
it = std::remove_if(MyIntVector.begin(),MyIntVector.end(),???);
[...]
As you can see I don't know how to write the unary predicate.
My starting point is simply this:
std::bind2nd(std::greater<int>(),2);
The way I see it this is a unary predicate taking an int as input.
How can I modify this predicate so it take an object MyInt as input
using the member function GetInt().
|
The only way to get the actual data value out of your class is the GetInt
() function, but you have not told to STL anywhere about this function,
so it's not surprising it fails. You either need to write a separate
function (object) which calls GetInt() somewhere, or you have to add some
more functions to your class which can access the data value (like
operator>(int) in this case, for example).
HTH
Paavo
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kwijibo28 Guest
|
Posted: Thu Dec 23, 2004 10:13 pm Post subject: Re: Using remove_if with a member function |
|
|
| Quote: | Your code has lots of problems. You may want to look at how to write a
copy constructor. Why does your class have virtual functions?
|
When I start a new class I use a macro in my IDE to generate a
skeleton. The default behaviour is to make the destructor virtual. If I
have not made my destructor virtual I'm sure that someone else would
have tell me to always make my destructor virtual unless I'm very sure
what I'm doing. (Potential problems if a try to derive from this
class...)
| Quote: | you are not providing a convenient way to initialize your member. You
will have
to provide other operators if you are trying to encapsulate an int.
|
I'm not trying to encapsulating a int. As a said in my original post
this is a toy problem to illustrated something I want to do with
remove_if. The actual class I'm using have nothing to do with an
integer.
| Quote: | You will have to be careful while erasing in a loop, because erase
might invalidate the iterator. you have to take the iterator returned
by the erase while
looping.
|
[snip]
Thank you very much for you're solution.
But I would have like to see the a solution with an actual accessor
like GetInt() since in my real world problem I'm stuck with sometime
like that.
kwijibo
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Fri Dec 24, 2004 9:25 pm Post subject: Re: Using remove_if with a member function |
|
|
kwijibo28 wrote:
| Quote: | Your code has lots of problems. You may want to look at how
to write a copy constructor. Why does your class have virtual
functions?
When I start a new class I use a macro in my IDE to generate a
skeleton. The default behaviour is to make the destructor
virtual. If I have not made my destructor virtual I'm sure
that someone else would have tell me to always make my
destructor virtual unless I'm very sure what I'm
doing. (Potential problems if a try to derive from this
class...)
|
So don't use the macro. A class is either designed to be
polymorphic, or it isn't. If it isn't designed to be
polymorphic, it doesn't need a virtual destructor. And if it
is, you can't put it in STL containers (or copy by value in
general).
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Dec 25, 2004 8:30 pm Post subject: Re: Using remove_if with a member function |
|
|
bread crumb mixture.
Fry till golden brown in 350° peanut oil.
In a baking pan, place a layer of gravy,
then one of meat, gravy, and cheese.
Another layer each of meat, gravy, and cheese.
Then bake at 350° for 45 minutes.
Serve on hot pasta with romano cheese.
Southern Fried Small-fry
Tastes like fried chicken, which works just as well.
In fact you may want to practice cutting up whole chickens
for frying before you go for the real thing.
Whole chicken is much more efficient and inexpensive than buying pieces.
1 tiny human, cut into pieces
2 cups flour
Onion, garlic
Salt
pepper
garlic powder
cayenne pepper
hot sauce, etc.
Oil for frying
Mix milk, eggs, hot sauce in a bowl, add chopped onion and garlic.
Season the meat liberally, and marinate for several hours.
Place seasoned flour in a paper or plastic shopping bag,
drop pieces in a few a time, shake to coat thoroughly,
then deep fry in hot oil (350°) for about 15 minutes.
Drain and place on paper towels.
Miscarriage with Mustard Greens
Why waste it? Otherwise, and in general, use ham or salt pork to season greens.
The technique of smothering greens can be used with many vegetables;
green beans work especially well. Meat is not necessary every day, don?t
be afraid to alter any dish to vegetarian tastes.
1 premature baby, born dead
Large bunch of mustard greens
2 white onions, 1 cup chopped celery
Vegetable oil (or hog fat)
Salt, pepper, garlic, e
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Sat Dec 25, 2004 9:39 pm Post subject: Re: Using remove_if with a member function |
|
|
you go for the real thing.
Whole chicken is much more efficient and inexpensive than buying pieces.
1 tiny human, cut into pieces
2 cups flour
Onion, garlic
Salt
pepper
garlic powder
cayenne pepper
hot sauce, etc.
Oil for frying
Mix milk, eggs, hot sauce in a bowl, add chopped onion and garlic.
Season the meat liberally, and marinate for several hours.
Place seasoned flour in a paper or plastic shopping bag,
drop pieces in a few a time, shake to coat thoroughly,
then deep fry in hot oil (350°) for about 15 minutes.
Drain and place on paper towels.
Miscarriage with Mustard Greens
Why waste it? Otherwise, and in general, use ham or salt pork to season greens.
The technique of smothering greens can be used with many vegetables;
green beans work especially well. Meat is not necessary every day, don?t
be afraid to alter any dish to vegetarian tastes.
1 premature baby, born dead
Large bunch of mustard greens
2 white onions, 1 cup chopped celery
Vegetable oil (or hog fat)
Salt, pepper, garlic, etc.
Lightly brown onions, celery, garlic and meat in large heavy pot.
Add a little water and the greens (which should be thoroughly cleaned and washed).
Smother slowly for at least 2 hours, adding small amounts of water
when it starts to stick.
Stir frequently.
When ready - serve with rice, grilled smoked sausage, green salad, and iced tea.
Coffee and apple pie then brandy.
Maternity Ward Pot Luck Dinner
If you can?t get anything fresh from the hospital, nursery, or morgue;
you can at least get rid of all the leftovers in your refrigerator.
1 - 2 lbs. cubed meat (human flesh, chicken, turkey, beef...)
1 -2 lbs. coarsely chopped vegetables
(carrots, potatoes, turnips, cauliflower, cabbage...)
Bell pep
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|