challenge: implement the max function
Andrei Alexandrescu (See Website For Email)
SeeWebsiteForEmail at erdani.org
Fri Jan 26 16:04:14 PST 2007
Kevin Bealer wrote:
> Here's my late entry:
>
> alias max_type(T, U) {
> static if (T.max > U.max) {
> alias T max_type;
> } else {
> alias U max_type;
> }
> }
So far so good.
> max_type(T, U) ALIAS max(T, U)(inout T x, inout U y)
> {
> alias max_type(T,U) MT;
> MT x1 = x, y1 = y;
>
> if (x1 >= y1) {
> static if (is (MT == T)) {
> return alias x;
> } else {
> return x1;
> }
> } else {
> static if (is (MT == U)) {
> return alias y;
> } else {
> return y1;
> }
> }
> }
This will not work when passed lvalues, a la:
auto b = max(a + 1, a - 1);
> The new feature is "return alias x", which is just syntax for saying
> that you are returning a reference to the input parameter.
The reference thing must be reflected in function's return type, not in
the function's return statement(s). This is for a number of reasons,
including separate compilation and ease of parsing.
> Note that "ALIAS" should be replaced by some keyword -- or maybe remvoed
> entirely, since it can be deduced easily as described below. It should
> be safe to remove it entirely since we can deduce it from the I was
> going to use "alias" but it looks too much like If D ever gets a keyword
> to indicate the opposite of C++'s "strict" keyword, I would think it
> could be used here.
I'm not sure what the purpose of ALIAS is. Was it to indicate that max
returns, or may return, a reference?
In any case, the entry needs some rework because of the reason above:
it's not sound to deduce storage from the function's return value,
without actually reflecting that storage in the statically-known return
type.
Moving on to the second entry...
> Solution Two
>
> NOTE: This is not a C++ "&", see below.
>
> template max(T, U) {
> static if (T == U) {
> T & max(T & x, U & y)
> {
> if (*x >= *y) {
> return x;
> } else {
> return y;
> }
> }
> } else {
> max_type(T, U) max(T, U)(T x, U y)
> {
> alias max_type(T,U) MT;
>
> if (x >= y) {
> return x;
> } else {
> return y;
> }
> }
> }
> }
>
> The "&" here is kind of like C++'s "&" type, but you can't use it except
> in function interfaces. In the context of a function argument, it means
> that the caller of the function is actually passing "& x" when they say
> "x", and in the case of a return value, the caller thinks they get
> something like "T x", but it they actually get a "T * x", and when they
> use it, the "x" turns into "*x".
What if I call max with two rvalues of the same type?
auto b = max(a + 1, a + 1);
> Inside the function body, no magic translations are done, the writer of
> the function use actual pointers to do the work to make it harder to
> accidentally return addresses of local variables.
>
> I think this satisfies A B C E F, though not as heroicly with C as the
> Solution One (which may be a good thing.)
But rvalue handling is not satisfactory, and besides there is the scary
code duplication. I'm afraid this candidate needs some rework too :o).
Andrei
More information about the Digitalmars-d
mailing list