Re: Return versus Side-Effect
On 30 Mar., 18:13, Brendan <catph...@catphive.net> wrote:
On Mar 27, 5:36 pm, "Niels Dekker - no return address"
[snip]
There are many cases where RVO can not or will not happen. Output
parameters on the other hand are a well known and highly readable
idiom.
Output parameters are not readable.
string in;
string out;
fun(in, &out);
Note that a pointer is passed instead of a reference for output
parameters so that you can tell easily at the point of invocation that
the out parameter is being modified. The signature looks like:
The invocation does not tell you that. It tells you that the second
parameter is a pointer, which can have lots of other causes - e.g.
that the parameter is optional.
void fun(const std::string& in, std::string* out);
The signature could also have been
void fun(const std::string& in, std::string const * out);
[snip]
Swapping a temporary is *far* less readable, maybe even outright
confusing. Additionally, it still isn't as efficient as:
string in;
string out;
fun(in, &out);
Well... the most efficient on any compiler worth its money (including g
++!) would be:
str?ng in;
string out = fun(in);
This way you avoid the superflouos constructor call as well as
whatever assignments that must take place inside fun.
By using the by value signature you are requiring the user to go
through extra hoops to get efficient code. The fact is that C++ has
large by value objects, and is not java or scheme or any other
language, and special C++ idioms are necessary to write efficient and
readable code.
C++0x is designed to alleviate this particular problem, but it isn't
going to be in compilers for years, so I think that out parameters are
the correct answer for today.
It is not. Out parameters are less readable than return values, and
often better performance-wise. There are examples of the opposite (as
Alexandrescus examples, where a buffer could be reused, saving a new
and a delete if used within a loop), but if the general usage is as
shown by you, the return-value is the more efficient one.
Also, some people have complained that out parameters are "premature
optimization," however I dispute this because
1. It's more of a common idiom that you should always use than some
kind of tricky "optimization." It's simply how you do things in c++,
even if it isn't in other languages.
No it is not.
2. Fixing this problem after the fact is a pain since it requires you
to make a change to every point of invocation. It's much easier to
just make out parameters your default idiom and be done with it.
What problem? IF there is a problem, it is not hard to fix:
1) replace the meat of your std::string fun(string const&) so that it
is replaced by fun(string const&, string&) or whatever you prefer.
This is the hard part as you have to give it special considerations
wrt exception guarantees, but it doesn't really matter as you saved
that time writing the first function.
2) create a new one-line function:
std::string fun(string const& s) { string res; fun(s,res); return
res; }
If you want to, you can make it inline. This function will be optimal
considering that RVO works (and as I already told you, it does on all
modern compilers).
3) Replace the one-parameter fun taking up to much time with your new
two-parameter one.
I would go so far as to say, that in C++ you should develop the habit
of never returning anything that isn't a primitive type or a pointer.
Really, returning things by value just leads to more operator
overloading. Very few classes really need to overload the assignment
operator.
What? This is rubbish.
/Peter
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]