Boost logo

Boost :

From: Noel Yap (Noel.Yap_at_[hidden])
Date: 2003-05-04 21:29:04


"Justin M. Lewis" wrote:
> > Yes, we have. One more time:
> >
> > T f(); // if T has a cheap copy
> > T const& f(); // if f owns the return value, can handle polymorphic
> > types
> > dumb_ref< T > f(); // if T doesn't have a cheap copy, f has to own the
> > return value, can handle polymorphic types
> > dumb_ptr< T > f(); // if the return value can be NULL, f has to own
> > the return value, can handle polymorphic types
> > result< T > f(); // if the return value is gotten from an asynchronous
> > call
> > tuple< T, U > f(); // if f has many return values, I think one can use
> > bind, too
>
> You're not passing the param in, so f either owns, or is allocating the
> object in every one of those cases, and that's not the case for every out
> param.

Perhaps our definitions differ then. I've been considering what you
just described to be an in/out parameter:

  void f( dumb_ref< T > inOut_ );

> An out param simply means that the function its being passed to does
> NOT care about the contents of the object, it is going to modify it in such
> a way that the current state of the object does not matter.

I see. I thought the whole point of the proposal was to spot where
variables may change. If so, what difference does it make whether it
changes via an out parameter or an in/out parameter? IIRC, you already
said that there's really no way to guarantee that out<> isn't really an
in_out<>.

> So, then the
> problem with your method becomes you have to new and delete all of those out
> params you're using,

This isn't completely true. When f owns the object being returned, the
storage can be dynamic, as you say, or it can be static, too.

> except in the case where f is a member function of an
> object where the out param is a member of the object, not always, the case,
> in fact, I'd say that's the uncommon case, where you return internal data
> from an object and give a handle to someone else to modify it.

I agree.

>From what I understand, then:
- you want to find where variables are modified
- you propose having in_out<> for in/out parameters
- you propose having out<> for out parameters but don't propose
preventing using it for in/out parameters
- you may want in<> for in parameters

I think having in<> and in_out<> will achieve the goal of being able to
spot easily where variables are modified.

Since out<> cannot be guaranteed to be solely out parameters, it's false
advertisement and, therefore, shouldn't be in the standard. Instead,
the other means of having out parameters should be used, including in
your situation, using in_out<>.

Going further, I think I've shown that in<> and in_out<> can be done
with just one class, dumb_ref<>:

  // hack together a template typedef
  template< typename T >
  class in:
    public dumb_ref< T const > // may want to use traits so that < T
const const > won't occur
  {
  };

  // hack together a template typedef
  template< typename T >
  class in_out: // may want to use concepts so < T const > won't occur
    public dumb_ref< T >
  {
  };

It'll still be a tough battle, but I think fighting for the inclusion of
one class that has the same interface as an already existing class is
much easier than fighting for the inclusion of two new classes.

HTH,
Noel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk