for_each and invoking self's member pointer

K

Kenneth Porter

I'm trying to create a class that represents a bucket of locks, and I
want to lock a set of objects specified by a container of pointers. I
can't seem to find the right combination of function adapters to invoke
the bucket's member function on each pointer in the argument container.
What's the right thing to use here, at the "???"?

#include <vector>
#include <functional>
#include <algorithm>

using namespace std; // keeps example simple

class BucketOfLocks;

class Lockable
{
BucketOfLocks* owner;
public:
void acquire(BucketOfLocks& newOwner) { owner = &newOwner; }
};

class BucketOfLocks
{
public:
BucketOfLocks(const vector<Lockable*>& lockables);
private:
// this is what I want to invoke in the for_each
void acquire(Lockable& lockable);
};

BucketOfLocks::BucketOfLocks(const vector<Lockable*>& lockables)
{
for_each(lockables.begin(), lockables.end(),
???(&BucketOfLocks::acquire,*this));
}
 
A

Alf P. Steinbach

* Kenneth Porter:
I'm trying to create a class that represents a bucket of locks, and I
want to lock a set of objects specified by a container of pointers. I
can't seem to find the right combination of function adapters to invoke
the bucket's member function on each pointer in the argument container.
What's the right thing to use here, at the "???"?

#include <vector>
#include <functional>
#include <algorithm>

using namespace std; // keeps example simple

class BucketOfLocks;

class Lockable
{
BucketOfLocks* owner;
public:
void acquire(BucketOfLocks& newOwner) { owner = &newOwner; }
};

class BucketOfLocks
{
public:
BucketOfLocks(const vector<Lockable*>& lockables);
private:
// this is what I want to invoke in the for_each
void acquire(Lockable& lockable);
};

BucketOfLocks::BucketOfLocks(const vector<Lockable*>& lockables)
{
for_each(lockables.begin(), lockables.end(),
???(&BucketOfLocks::acquire,*this));
}

class BucketOfLocks
{
public:
BucketOfLocks(const vector<Lockable*>& lockables);
private:
// this is what I want to invoke in the for_each
void acquire(Lockable* lockable) {}
};

BucketOfLocks::BucketOfLocks(const vector<Lockable*>& lockables)
{
for_each(lockables.begin(), lockables.end(),
bind1st( mem_fun<void>( &BucketOfLocks::acquire ), this )
);
}

At least it compiles; I haven't tested it.

By the way, why are you using for_each, why not simply use a for loop?


Cheers, & hth.,

- Alf
 
K

Kenneth Porter

By the way, why are you using for_each, why not simply use a for loop?

Flexibility. I can change the container type without changing the code that
iterates over it.

Alas, I need to continue to use VC6 to support some customers and will need
to cripple my STL template usage a bit for awhile.
 
C

Chris Thomasson

Kenneth Porter said:
A "lock" in the conventional mutex sense may be a misnomer here.
Attempting
to acquire a held lock in my system is considered an error, not something
to be waited for.

Okay. Sorry for all the questions, but, are your using traditional
two-phased locking based on try_lock/back-off logic?
 
K

Kenneth Porter

Okay. Sorry for all the questions, but, are your using traditional
two-phased locking based on try_lock/back-off logic?

No, I just throw a busy exception if the lock is already held, and the
application pops up an error. Scheduling of resources is supposed to be
handled elsewhere, and a lock failure at this level indicates a programming
error.
 
C

Chris Thomasson

Kenneth Porter said:
No, I just throw a busy exception if the lock is already held, and the
application pops up an error. Scheduling of resources is supposed to be
handled elsewhere, and a lock failure at this level indicates a
programming
error.

Okay. I see.
 
K

Kai-Uwe Bux

Kenneth said:
Flexibility. I can change the container type without changing the code
that iterates over it.
[snip]

That can be achieved using just a typedef:

typedef std::vector< ticket > ticket_sequence;
...
for ( ticket_sequence::iterator iter = ... ) {
...
}

Now you can change from vector to deque by modifying a single line.


In fact, one can consider using std::vector< whatever > directly instead of
using a typedef to be the typesystem analogue of using a magic number like
12341 instead of a named constant

int const number_of_runs = 12341;


Best

Kai-Uwe Bux
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top