Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-04-24 04:05:02


>From: "Justin M. Lewis" <boost_at_[hidden]>

> 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_out<type> may_change, const type &may_not_change);
// Your method

boost::tuple<int, 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::optional<type> 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


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