Re: More keyword abomination by C++0x
Newbie's questions would just be different. There would be _no_ posts
about
const references to temporaries and references as l-values and r-values
or
std::swap ;o)
Yes, there would. Take for example the following program using your
rules for operator overloading.
struct foo_t
{ foo_t* operator+= (int* y) { *y = 3; }
};
int main()
{ foo_t f;
long z = 2;
f += z;
return z;
}
The problem is implicit conversions. Implicit conversions are why we
have questions about binding a non-const ref to a temporary.
The only reasonable option I see for the above program is don't
compile. You are trying to bind a non-const reference (or pointer in
this case) to the result of an implicit conversion from long to int, a
temporary. The alternative would be to allow writing to the temporary,
but the above program would return 2, not 3, and we would instead get
a lot of questions on that, and a lot of hassle from competent
programmers about implicit conversions being the devil. (I suppose an
alternative would be to outlaw all implicit conversions, but I think
that's going quite overboard.)
Implied conversions would not occur with a pointer calling convention so the
above would fail to compile. The implied pointer [;)] would be a long* so it
wouldn't match to the operator += you have specified as the types are
unrelated. The only implied conversions using a pointer are when you
dereference it and do something with it... or cast it...
Your program would be equivalent to...
struct foo_t {
foo_t* operator_plusequal (int* y) {*y=3; return this;}
};
int main()
{
foo_t f;
long z = 2;
f = *(f.operator_plusequal(&z));
return z;
}
You'd get a message like:
E:\t2\main.cpp(13) : error C2664: 'operator_plusequal' : cannot convert
parameter 1 from 'long *' to 'int *'
Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast
You'd have had to make more overloads or write template operators to sweep
up everything if implied conversion was desired.
e.g.
struct foo_t {
template<class T> foo_t* operator+=(T* y) { *y=3;}
}
References are a red herring. The real problem is implicit conversions
in function arguments creating temporaries, implicitly aka without any
source code to do the conversion, and this may surprise people if
they're allowed to modify that temporary in the function but the
temporary is immediately destroyed, leaving the source of the implicit
conversion unchanged.
Agreed about the problem but it is references which allow this problem
behaviour. There are no conversions for a pointers underlying type so
without references there are only implied conversions passing by _value_ -
people know not to expect the answer to be returned. People feel (including
me) that references should be able to do 'pointer stuff' and so don't think
carefully about using them - the program is legal & compiles but doesn't
have the desired behaviour. That is evil ;)
(side note, why should I have to think carefully? Isn't that what compiler
diagnostics and strict typing are for??)
Chris
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]