Re: Check if an argument is temporary
On Oct 30, 9:26 am, James Kanze <james.ka...@gmail.com> wrote:
On Oct 29, 4:22 pm, gpderetta <gpdere...@gmail.com> wrote:
On Oct 29, 1:45 pm, Erik Wikstr=F6m <Erik-wikst...@telia.com> wrote:
On 2007-10-29 12:27, gpderetta wrote:
[...]
Make A::operator= take the argument by Value instead of
reference, then swap 'this' and the argument:
So you remove one copy and create a new. By taking the
argument by value a copy must be made so nothing is won.
It is the asignment operator, so, yes, you need to do at least one
copy.
Not necessarily. If the argument to the operator= is a value,
rather than a reference, the compiler can use RVO or NRVO when
it constructs it; roughly speaking, the array that is being
constructed in foo() will be the one that the operator= sees.
Yes, you are right. What should have said, is that you need to invoke
an expensive
constructor at least once, wheter inside a function which does NRVO,
or initializing the
argument of a
Consider
the canonical exception safe operator=:
A& A::operator=(A const& rhs) {
A tmp(rhs);
using std::swap;
swap(*this, rhs);
return *this;
}
You have to do a copy anyway, but if you capture by value
instead of reference, you save a copy if the argument was an
rvalue anyway.
[...]
If the
profiler says that the copy is a bottleneck, however, it's not
something so important that I'd let it stop me from using the
value. In such cases, it is a definite improvement in
performance; if the compiler correctly implements RVO and NRVO
(and many do), then you may easily end up without any copies
what so ever; a new object is constructed with its new values in
the function, and that object is swapped with the existing one
in the operator=.
The reason I often do not bother with this optimization is that the
standard library I usually use doesn't do it for standard containers,
so I have the habit to never (re)assign potentially heavy objects.
I usually do a a copy initialization or use a swap member:
A foo();
....
A x;
....
foo().swap(x);
There are doubtlessly other solutions, based on helper classes,
which can also be used. They are significantly more complex,
but can be made to avoid the copy even if the compiler doesn't
implement NRVO or RVO.
Yes, you can implement move sematics in C++03, but it is a bit
involved, and where would you need them the most (inside std
containers),
they can't be used (unless you reimplement the containers of course).
Is there any relatively modern compiler which doesn't do NRVO or RVO
(in most reasonable cases at least) or doesn't
eliminate temporaries used in copy initialization?
--
Giovanni P. Deretta