Re: What's the point of passing parameter by value (vs. const ref)
--=-=-=
on Thu Jul 03 2008, Marcin.Barczynski-AT-yahoo.com wrote:
On Jul 2, 10:58 am, "Martin T." <0xCDCDC...@gmx.at> wrote:
When writing new C++ code, what is the point of passing any (input)
parameter by value when passing by const reference will just work as
well? (Even and especially PODs, I would not do it with a complex type
anyway.)
(Given that in 90% of the code you will never want to modify the
parameter anyway.)
References are implemented as pointers, so whenever you use a
reference parameter in your functions, two readings are performed:
value of a pointer to the passed variable and the variable itself.
As copy-constructors of built-in types are cheap, it's usually more
efficient to pass them by value. The same applies to STL iterators.
For all other types passing by const reference is preferable.
Not necessarily. For example, try running the program below. With my
compiler it prints the following
default ctor
=== by reference ===
default ctor
copy ctor
swap
dtor
dtor
=== by value ===
default ctor
swap
dtor
=== done ===
dtor
which demonstrates that passing by reference can cause twice as many
copies as passing by value when the source is an rvalue. That can
really add up when the source is expensive to copy like a
vector<string>. If you're going to copy the argument anyway, you're far
better off passing it by value and swapping it into position. That
allows the compiler to elide the copy used to create the parameter value
(inside the function) when the argument (outside the function) is an
rvalue.
--=-=-=
Content-Type: text/x-c++src
Content-Disposition: inline; filename=elision.cpp
#include <utility>
#include <iostream>
struct trace
{
trace() { std::cout << "default ctor\n"; }
trace( trace const& ) { std::cout << "copy ctor\n"; }
trace& operator=( trace const& ) { std::cout << "copy assign\n"; return *this; }
~trace() { std::cout << "dtor\n"; }
friend void swap( trace& x, trace& y ) { std::cout << "swap\n"; }
};
template <class T>
struct holder
{
void set_by_value(T x)
{
using std::swap;
swap(x, held);
}
void set_by_reference(T const& x)
{
T tmp(x);
using std::swap;
swap(tmp, held);
}
private:
T held;
};
int main()
{
holder<trace> h;
std::cout << "=== by reference ===\n";
h.set_by_reference( trace() );
std::cout << "=== by value ===\n";
h.set_by_value( trace() );
std::cout << "=== done ===\n";
}
--=-=-=
--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
--=-=-=--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]