|
Boost Users : |
From: Trent Hill (trent.hill_at_[hidden])
Date: 2005-01-06 18:20:14
Hi Peter,
Peter Dimov wrote:
<snip>
>> Four copies - I had hoped to only see a single copy. Logically, there
>> doesn't seem to be a need for more than one copy. Is there an
>> implementation issue that requires this many copies?
>
>
> Not really, but eliminating the unnecessary copies is (relatively) hard,
> at least with the current code base (it has been developed with
> portability in mind and supports VC6, among others). The specification
> requires one copy. One more is almost unavoidable. The other two can be
> eliminated, in theory. But...
Ok, thanks. Out of interest, is there a simple explanation for why one
more is almost unavoidable.
<snip>
> ... please note that the copies occur at bind time. In a typical
> scenario you bind once and call O(N) times (or bind and store in a
> function<> with the associated dynamic memory allocation), so this isn't
> usually a problem. And, as others have pointed out, there's always
> ref(). ;-)
Yes I understand. I guess I'm not using bind typically ;-)
FYI and for those suggesting boost::ref, the actual case is using bind
for message passing between threads. I have a polymorphic wrapper for
bind something like this:
class bind_wrapper
{
public:
virtual void execute() = 0;
};
template <typename binder_t>
class bind_wrapper_impl : public bind_wrapper
{
public:
bind_wrapper_impl(const binder_t &binder_a)
: binder_m(binder_a)
{
}
virtual void execute()
{
binder_m();
}
private:
binder_t binder_m;
};
template <typename binder_t>
std::auto_ptr<bind_wrapper>
make_bind_wrapper(const binder_t &binder_a)
{
return std::auto_ptr<bind_wrapper>(
new bind_wrapper_impl<binder_t>(binder_a));
}
Now the idea is that certain functions transparently transfer work to a
worker thread. So for such a function "foo", there would be an internal
implementation function:
void foo_impl(const std::string &string_a)
{
// do stuff
}
and a public proxy that requests foo_impl to be called on the worker thread:
future foo_async(const std::string &arg_a)
{
std::auto_ptr<bind_wrapper> message_l(
make_bind_wrapper(boost::bind(&foo_impl, arg_a)));
// add message_l to message queue and return future to allow
// rendezvous
...
}
The worker thread will collect this message and call execute(),
something like:
void worker_thread()
{
// retrieve from message queue and execute
std::auto_ptr<bind_wrapper> message_l = ...
message_l->execute();
}
So, in this case:
1. Yes, a copy is required - boost::ref is not appropriate.
2. Each bind corresponds to a single call (not O(N) calls)
We have a home grown solution (less general than bind of course)
requiring only a single copy. I was hoping to replace it with bind but
it's hard to justify adding the extra argument copies.
Thanks for the info though,
Cheers, Trent.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net