> >> async_result<double> res;
> >> thread t(bind(res.call(), a, b, c));
> >> // do something else
> >> d = res.value();  // Explicitly waits for the thread to return a
> >> value?
> >
> > This does the same, indeed. Starting a thread this way is just a little
> > more complex (and -- in my view -- less obvious to read) than writing
> >   thread t = spawn(foo)(a,b,c);
> 
> Not sure I agree about "less obvious to read".  If your syntax had been
>    thread t = spawn(foo, a, b, c);
> I think you'd have a bit more of an argument here.  And I certainly could
> fold the binding directly into boost::thread so that my syntax would
> become:
> 
> thread t(res.call(), a, b, c);
> 
> I could even eliminate the ".call()" syntax with some implicit
> conversions, but I dislike that for the obvious reasons.  I specifically
> chose not to include syntactic binding in boost::thread a long time ago,
> because I prefer the explicit seperation of concerns.  So, where you think
> my syntax is "less obvious to read", I think it's "more explicit".

If you do all this, then you'll probably almost arrive at the code I 
posted :-)

Still, keeping the analogy to the usual call foo(a,b,c), I prefer the 
arguments to foo in a separate pair of parentheses. However, there is 
another point that I guess will make your approach very hard: assume
    void foo(int, double, char);
and a potential constructor for your thread class
    template <typename A, typename B, typename C>
    thread (void (*p)(A,B,C), A, B, C);
Then you can write
    foo(1,1,1)
and arguments will be converted automatically. However, you cannot write
    thread t(foo, 1, 1, 1);
since template parameters must be exact matches.

There really is no other way than to first get at the argument types in a 
first step, and pass the arguments in a second step. You _need_ two sets 
of parentheses to get the conversions.


> > Actually it does duplicate the work, but not because I am stubborn. We
> > have an existing implementation for a couple of years, and the present
> > version just evolved from this. However, there's a second point: when
> > starting threads, you have a relatively clear picture as to how long
> > certain objects are needed, and one can avoid several copying steps if
> > one  does some things by hand. It's short anyway, tuple type and tie
> > function  are your friend here.
> 
> I'm not sure how you avoid copies here.

Since you have control over lifetimes of objects, you can pass references 
instead of copies at various places.


> >   t->kill ();
> >   t->suspend ();
> > Someone sees that there's a function yield() but doesn't have the time
> > to  read the documentation, what will he assume what yield() does?
> 
> How does "someone see that there's a function yield()" with out also
> seeing that it's static?  No need to read documentation for that, as it's
> an explicit part of the functions signature.

Seeing it used in someone else's code? Just not being careful when reading 
the signature?

I think it's the same argument as with void* : if applied correctly it's 
ok, but in general it's considered harmful.

W.

-------------------------------------------------------------------------
Wolfgang Bangerth             email:            [EMAIL PROTECTED]
                              www: http://www.ticam.utexas.edu/~bangerth/


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Reply via email to