Boost logo

Boost :

From: Reece Dunn (msclrhd_at_[hidden])
Date: 2003-04-24 13:02:02


"Justin M. Lewis" wrote:
> > > > > in/out seems to be used fairly commonly in COM. I'm not sure I
>have any > > great examples off the top of my head, but I know they're
>commonly used.

> > I'm not a COM person, but I believe it's written in C. If so, then you
> > are correct that in/out parameters are more needed since noone would >
>want to create a struct for each multiple return type.

> > OTOH, C++ has templates to deal with this situation (ie boost::tuple<>)
> > so, qualifying my previous statement, in C++ I still see no need for >
>in/out parameters.

>I think most COM objects are written in C++. I should have been more
>specific here, if you're looking at ActiveX objects, in/out params are used
>all over the place. Each function returns an HRESULT, iirc, any data you
>want returned has to be returned in a param.

The COM object interfaces are actually written in Microsoft-variant IDL, in
a similar way to CORBA. The MIDL compiler then generates C++ abstract
classes *and* C structures, so you can use either C or C++. In fact, you can
use any supported language (Pascal, Java, etc).

Because COM interfaces are in effect language independant, you cannot use
the exception mechanism, so MS decided to use error code return values,
hence the HRESULT return type.

This is an example of a much larger problem that the parameter = in; return
= out methodology cannot cover: what if your function has more than one
return data items? For example:

   inline void sincos( float theta, float s, float c )
   {
      s = std::sin( theta );
      s = std::cos( theta );
   }

You could use the std::pair type for a return value, but this would
complicate the code:

   std::pair< float, float > sc = sincos( 0.75 );
   std::cout << "theta = 0.75: sin = "
             << sc.first << "; cos = "
             << sc.second << "\n";

vs

   float sinval, cosval;
   sincos( 0.75, sinval, cosval );
   std::cout << "theta = 0.75: sin = "
             << sinval << "; cos = "
             << cosval << "\n";

I find the latter easier to read.

The issue that this proposal is trying to solve is the modification of
variables inside a function. Isn't this what const is for?

   inline int f( const std::list< int > & li )
   {
      return( *li.front()); // first item
   }

in - by value; const reference
out - return; reference
in/out - reference

IMHO, this makes more sense than having to use special wrappers that
complicate the code and make it harder to read and maintain.

If you are worried about an object being modified, use a temporary:

   std::complex< float > c1( 1.0, 2.5 );
   std::complex< float > ctemp( c1 );
   if( modifyComplex( ctemp ))
   {
      // do something
   }

but this should not be needed in most cases, especially when using const
references.

Just my 2 cents worth.

-rhd-
mailto:msclrhd_at_[hidden]

_________________________________________________________________
Worried what your kids see online? Protect them better with MSN 8
http://join.msn.com/?page=features/parental&pgmarket=en-gb&XAPID=186&DI=1059


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