 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
unspammable@gmail.com Guest
|
Posted: Wed Sep 28, 2005 10:03 pm Post subject: predicates and binding "this" |
|
|
How can I bind a pointer to the "this" argument of a member function?
I have a class:
class Garage {
bool carStinks(const Car& c) { ... }
}
and a collection of cars that I want to filter:
remove_if(
cars.begin(),
cars.end(),
?????????);
// and call erase afterwards
How can I filter out cars that stink, using the given member function?
I want to be able to do something like this pseudo code:
Garage g;
remove_if(
cars.begin(),
cars.end(),
bindThis(mem_fun(&Garage::carStinks), &g));
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Cottrell Guest
|
Posted: Thu Sep 29, 2005 3:00 pm Post subject: Re: predicates and binding "this" |
|
|
[email]unspammable (AT) gmail (DOT) com[/email] wrote:
| Quote: | How can I bind a pointer to the "this" argument of a member function?
I have a class:
class Garage {
bool carStinks(const Car& c) { ... }
}
|
'this' is a "pointer to the current object". Returning 'this' from a
member function of an object of type 'Garage' would point to the Garage
object, not a Car object.
Aside from which, your member function already has a reference to your
Car object in its parameters.
| Quote: | and a collection of cars that I want to filter:
remove_if(
cars.begin(),
cars.end(),
?????????);
// and call erase afterwards
How can I filter out cars that stink, using the given member function?
I want to be able to do something like this pseudo code:
Garage g;
remove_if(
cars.begin(),
cars.end(),
bindThis(mem_fun(&Garage::carStinks), &g));
|
Unless I misunderstand your problem, you have a container of Car called
'cars' and wish to erase all objects of Car where carStinks returns
'true'. If I have misunderstood, the rest of my reply may not be
appropriate.
Firstly I suggest the function CarStinks() would be better off inside
class Car, since I would expect the return value be specific to each Car
object.
eg,
class Car
{
bool CarStinks;
public:
bool Stinks() { return CarStinks; }
}
//Removing objects from 'cars' where Stinks() returns 'true'
//assumption: object 'cars' is of type std::vector<Car>
typedef std::vector<Car>::size_type vecsize;
for (vecsize s = cars.begin(); s != cars.end(); ++s)
{
if ( cars[s].Stinks() )
cars.erase(s);
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Gianluca Silvestri Guest
|
Posted: Thu Sep 29, 2005 8:14 pm Post subject: Re: predicates and binding "this" |
|
|
<unspammable (AT) gmail (DOT) com> ha scritto nel messaggio
news:1127937262.998638.207200 (AT) g44g2000cwa (DOT) googlegroups.com...
| Quote: | How can I bind a pointer to the "this" argument of a member function?
I have a class:
class Garage {
bool carStinks(const Car& c) { ... }
}
and a collection of cars that I want to filter:
remove_if(
cars.begin(),
cars.end(),
?????????);
// and call erase afterwards
How can I filter out cars that stink, using the given member function?
I want to be able to do something like this pseudo code:
Garage g;
remove_if(
cars.begin(),
cars.end(),
bindThis(mem_fun(&Garage::carStinks), &g));
|
remove_if(cars.begin(), cars.end(),
std::bind1st(std::mem_fun(&Garage::carStinks), &g));
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Thu Sep 29, 2005 8:41 pm Post subject: Re: predicates and binding "this" |
|
|
[email]unspammable (AT) gmail (DOT) com[/email] wrote:
| Quote: | How can I bind a pointer to the "this" argument of a member function?
I have a class:
class Garage {
bool carStinks(const Car& c) { ... }
}
and a collection of cars that I want to filter:
remove_if(
cars.begin(),
cars.end(),
?????????);
// and call erase afterwards
How can I filter out cars that stink, using the given member function?
I want to be able to do something like this pseudo code:
Garage g;
remove_if(
cars.begin(),
cars.end(),
bindThis(mem_fun(&Garage::carStinks), &g));
|
I must say that it is refreshing to see code from a real-world C++
application - and one tackling real problems - instead of just another
contrived foo/bar program.
The obstacle that prevents iterating over and erasing stinky cars in a
container, is that there are two objects involved in the process: a
Garage and a Car. std::mem_fun calls a member function only on the
object being iterated over.
So I would first ask whether this problem requires the involvement of
both the Garage and the Car. If the car stinks, would it not always
stink? no matter where it was parked? Why is it necessary to query the
Garage, instead of the Car itself whether the car stinks? Now some
questions it would make sense to ask the Garage, such as whether the
Garage stinks, or whether it contains the car. But details soley
concerning the car itself and which are not dependent on the Garage,
should be available directly from the car. Therefore the class Car
should offer a method, IsSmelly(). Adding this method also solves the
problem on hand; since the Garage in no longer involved in the
stinkiness test, the program can use mem_fun to iterate and delete
stinky cars from a container:
v.erase( std::remove_if( v.begin(),
v.end(),
std::mem_fun(&Car::IsSmelly)),
v.end());
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
stevejay Guest
|
Posted: Sat Oct 01, 2005 1:31 am Post subject: Re: predicates and binding "this" |
|
|
[email]unspammable (AT) gmail (DOT) com[/email] wrote:
| Quote: | How can I bind a pointer to the "this" argument of a member function?
|
Hi,
Search for a thread on this group called:
'Using "for_each" to call a member function argument'
Bye,
Steve
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Mon Oct 03, 2005 1:18 pm Post subject: Re: predicates and binding "this" |
|
|
On 29 Sep 2005 11:00:47 -0400, Ben Cottrell
<bench (AT) bench333 (DOT) screaming.net> wrote:
| Quote: | Firstly I suggest the function CarStinks() would be better off inside
class Car, since I would expect the return value be specific to each Car
object.
eg,
class Car
{
bool CarStinks;
public:
bool Stinks() { return CarStinks; }
}
|
A reasonable suggestion.
| Quote: | //Removing objects from 'cars' where Stinks() returns 'true'
//assumption: object 'cars' is of type std::vector<Car
typedef std::vector
|
In the below code, you use a size_type once and iterators three times.
I guess you intended to use iterators. I will keep the bad name to
minimize changes below.
typedef std::vector<Car>::iterator vecsize;
| Quote: | for (vecsize s = cars.begin(); s != cars.end(); ++s)
{
if ( cars[s].Stinks() )
|
if (s->Stinks())
This is an excellent example of why standard algorithms should be
prefered to user code. Of minor importance, this algorithm is O(N*N)
while the standard cars.erase(remove_if ...) form is O(N). Of major
importance, the standard algorithm is correct. First, the erase(s)
invalidates s and any further use is undefined behavior. If we assume
that we get the usual undefined behavior of simply pointing to the next
value of the original set of data, there are other problems.
^T T erase gives ^T and ++ gives T ^ missing the second item.
^T erase gives ^ and ++ runs off the end forever.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Valentin Samko Guest
|
Posted: Thu Oct 06, 2005 1:39 pm Post subject: Re: predicates and binding "this" |
|
|
[email]unspammable (AT) gmail (DOT) com[/email] wrote:
| Quote: | How can I bind a pointer to the "this" argument of a member function?
I have a class:
class Garage {
bool carStinks(const Car& c) { ... }
}
....
How can I filter out cars that stink, using the given member function?
I want to be able to do something like this pseudo code:
Garage g;
remove_if(
cars.begin(),
cars.end(),
bindThis(mem_fun(&Garage::carStinks), &g));
|
If you can use the Boost.Bind library (which may end up in the next C++
standard), it is just
remove_if(
cars.begin(),
cars.end(),
boost::bind(&Garage::carStinks, &g, _1)
);
--
Valentin Samko - http://val.samko.info
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| 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
|
|