Re: [boost] Re: Re: class proposal

2003-04-24 Thread Terje Slettebø
From: Justin M. Lewis [EMAIL PROTECTED]

 As for a function returning a single param, I agree, normally you'd just
 return it, UNLESS it's some big structure you don't want being copied
 all over the place, then passing it by reference to a function makes
 more sense.

The compiler may elide such copy, even if the temporary being returned is a
named variable, and several compilers (such as g++ and the EDG based ones),
does this optimisation (RVO). For example:

class big_class { ... };

big_class f(...)
{
  big_class temp;

  ...

  return temp;
}

 // Only the constructor is called, here, no copy constructor

big_class value = f(...);

Also, if you want to return multiple values, std::pair or boost::tuple may
be used for that, as Noel Yap pointed out.

I understand the motivation is to transform a lot of existing code into
something that may be more easily understood. However, an alternative to
your method is to use techniques that has been proposed in this thread. For
example:

int return_value = f(type may_change, const type may_not_change); //
Current function

int return_value = fA(c_outtype may_change, const type may_not_change);
// Your method

boost::tupleint, type fB(const type may_not_change); // Alternative

Use:

type value;

int return_value = fA(out(value), const_value); // Your method

int return_value;

boost::tie(return_value, value) = fB(const_value);

Also, you may enforce that the parameters aren't changed, by using const:

const type const_value = ...;

fA(const_value, ...); // Error, can't bind to non-const reference

This may be a larger refactoring than adding out() and in_out(), though,
especially for a large code base, as you mention. I'm just concerned with
that out() and in_out() isn't a very common way to do it, so it may be best
to do it in an idiomatic way, to begin with.

Also, statements like:

boost::tie(return_value, value) = fB(const_value);

stands out in the code, rather than being more hidden with an out(). Thus,
they may have a better chance of being possibly further refactored. Say that
the return code says whether or not a valid object is returned. This may be
changed to:

boost::optionaltype result = fB(const_value);

Or maybe throwing an exception would be more appropriate:

type value = fB(const_value); // Throws on failure

The point really is the same as with your proposal - making it explicit in
the code what is happening.


Regards,

Terje

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


Re: [boost] Re: Re: class proposal

2003-04-24 Thread Terje Slettebø
Just to add some to my previous posting.

Also, from a maintenance POV, having variables that doesn't change
throughout a function (or program), tends to make it easier to understand.
Having functions which change their arguments goes rather against that.

One exception is input stream operators, where it's really no other way of
doing it than first declaring a variable, then streaming into it.

For example:

const some_type valueA=...;

const some_type valueB = f(valueA);

// Possibly many lines of code here

// What is valueA and valueB here? Answer: The same as when they were
declared.

Yes, I know it may be a massive undertaking to start making a program, which
wasn't designed that way, const correct. However, it may be one of the
better refactorings to do. It also highlights all the points where something
may be changed, and where further refactorings (such as those in the
previous posting) may be appropriate.


Regards,

Terje

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


Re: [boost] Re: Re: class proposal

2003-04-24 Thread Noel Yap
Terje Slettebø wrote:
 The part about RVO was really concerned with the out() scenario, not
 in_out(). I'm not sure if passing a smart pointer buys you very much. In
 this case, the smart pointer is const but the pointee is not, so the const
 in the signature is really just masking what is going on.

You're right.  I see your point.

At first I thought that if there were an easy way to convert smart_ptr
T  to smart_ptr T const  there'd be no problem.  But then I realized
this would bring about the expensive copy again.

IMHO, the solution to this dilemna is to use the de facto standard way
of using references like you said earlier:

  void f( T value_may_change_, T const value_may_not_change_ );

Noel
-- 
NOTICE: If received in error, please destroy and notify sender.  Sender
does not waive confidentiality or privilege, and use is prohibited.
___
Unsubscribe  other changes: http://lists.boost.org/mailman/listinfo.cgi/boost


[boost] Re: Re: class proposal

2003-04-23 Thread Bo Persson

Justin M. Lewis [EMAIL PROTECTED] skrev i meddelandet
news:[EMAIL PROTECTED]
 Not entirely, passing a pointer doesn't tell you that the parameter will
 change, it just tells you that it might, it still leaves you in the
position
 of having to track down the function and check it.  But outside of that,
if
 you're like me, at this point you prefer references to pointers, whenever
 possible.

The obvious solution is of course to name the function so that you can tell
what is does! :-)

A function returning a single value, should really RETURN the value and not
update a parameter:


y = year_of_first_marriage();


Having a function lying about its purpose should be caught at its
definition, not at each call of the function:

void will_never_change_any_parameters_honest(int x) { x = 7; }

is easy to catch early. :-)



Bo Persson
[EMAIL PROTECTED]




 - Original Message -
 From: Vincent Finn [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Wednesday, April 23, 2003 2:09 AM
 Subject: [boost] Re: class proposal


  
   void func(int x){x = 1977;};
  
   void blah()
   {
 int y=0;
 func(y);
 func2(y);
 printf(%d\n, y);
   }
  


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


RE: [boost] Re: Re: class proposal

2003-04-23 Thread Justin M. Lewis
It's not always that easy to give a function a name that will tell you
at invocation time which of it's parameters it's planning on changing,
and, it would be hard to tell people through just a function name that a
parameter is an in/out parameter.

As for a function returning a single param, I agree, normally you'd just
return it, UNLESS it's some big structure you don't want being copied
all over the place, then passing it by reference to a function makes
more sense.

Or, in the case I originally created this for, I had a function that
initialized an object to begin a transaction, I wanted to pass an object
into my function, and have it properly initialized to start a
transaction.  Anyway, in that case, InitRequest makes it pretty clear
that the object being passed is going to be modified, but by making it a
c_out param, there's NO question, it's explicit at the invocation.


-Original Message-
From: [EMAIL PROTECTED]
[mailto:[EMAIL PROTECTED] On Behalf Of Bo Persson
Sent: Wednesday, April 23, 2003 11:32 AM
To: [EMAIL PROTECTED]
Subject: [boost] Re: Re: class proposal


Justin M. Lewis [EMAIL PROTECTED] skrev i meddelandet
news:[EMAIL PROTECTED]
 Not entirely, passing a pointer doesn't tell you that the parameter
will
 change, it just tells you that it might, it still leaves you in the
position
 of having to track down the function and check it.  But outside of
that,
if
 you're like me, at this point you prefer references to pointers,
whenever
 possible.

The obvious solution is of course to name the function so that you can
tell
what is does! :-)

A function returning a single value, should really RETURN the value and
not
update a parameter:


y = year_of_first_marriage();


Having a function lying about its purpose should be caught at its
definition, not at each call of the function:

void will_never_change_any_parameters_honest(int x) { x = 7; }

is easy to catch early. :-)



Bo Persson
[EMAIL PROTECTED]




 - Original Message -
 From: Vincent Finn [EMAIL PROTECTED]
 To: [EMAIL PROTECTED]
 Sent: Wednesday, April 23, 2003 2:09 AM
 Subject: [boost] Re: class proposal


  
   void func(int x){x = 1977;};
  
   void blah()
   {
 int y=0;
 func(y);
 func2(y);
 printf(%d\n, y);
   }
  


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

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