Re: Check if an argument is temporary
On Oct 29, 1:45 pm, Erik Wikstr=F6m <Erik-wikst...@telia.com> wrote:
On 2007-10-29 12:27, gpderetta wrote:
On Oct 29, 11:53 am, Klaas Vantournhout <no_valid_em...@spam.com>
wrote:
James Kanze wrote:
The real question is why the OP wants to know. There's likely a
solution to his real problem which doesn't require such
knowledge.
Hmm okay this is what I had in mind.
Assume you have a class array
class array {
public:
array(int N) : n(N) {
if (n) a = new double[N];
else a = NULL;
}
~array(void) { delete [] a; }
array operator=(const array &A) {
if (n != A.n) { delete [] a;
a = new double [A.n]; }
for (register int i=N-1; i >= 0; --i)
a[i] = A.a[i];
return *this;
}
private
double *a;
int n;
}
Assume now we have the function
array foo(void);
which creates an enormous array
Then the following operation
array B;
B = foo();
Creates a tremendous amount of overhead.
A temporary array is created in foo(), this array is passed to operato=
r=
and there each element of foo is copied to B.
However, it would be useful if operator= could notice if the object =
is
temporary.
Because then we could write
if (temporary) {
a = A.a; A.a = NULL;
}
When this happens, foo gets destroyed after operator=, but it is onl=
y a
NULL pointer, the real date is still there and not delete with ~array(=
void);
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. 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.
The solution to the problem is called R-value References or Move
Semantics and will be part of the next version of the standard. Using
this you will be able to write move-constructors which transfers
ownership from the temporary to the new object.
Sure, R-Value references are a wellcome addition. But a take-by-value
operator= can
implemented *now* without language changes. And anyway, if you are
willing to do some
scafold work, move semantics are implementable in C++03 without
language extensions, see
the works of Alexandrescu and Abrahams. (the take take-by-value
operator= is an
useful subset of that).
--
Giovanni P. Deretta