Rainer Deyke wrote:
Steven Schveighoffer wrote:
Sure, do whatever you want for your *private data members*. I see too
much value in Optional!T being aliased to the underlying T to go for the
completely generic solution which requires special syntax to get at the T.
And I see no value at all, but a lot of danger.
The value is in the fact that you can use an Optional!T as a substitute
for a T. Actually that's quite what happens today with null references -
we know they can't be used, but they are substitutable for valid objects.
Even ignoring, what
about this:
void f(ref int v) {
// Do something...
}
void g() {
Optional!int x = 5;
f(x);
}
Such code should not compile. An Optional!T should be at most
substitutable for an rvalue of type T.
Or this:
void report_error(int);
void f(T)(out T v) {
if (error_condition) throw new SomeException();
v = something;
}
void g() {
Optional!int v = someCalculation();
if (!isNull(v)) {
try {
f(v);
} catch (SomeException) {
report_error(v); // Oops, invalid: 'v' turned into null.
}
}
}
Note how in the second example, the semantics of the function 'f' subtly
change depending on whether the argument is an 'int' or and 'Optional!int'.
If it's an int, you assign the int. If it's an Optional!int, you assign
the optional, which assigns the int and makes the Optional non-null if
it was null. I might be missing something, but I don't think there's
much danger for confusion here.
Proxies, especially proxies that add functionality to their base type,
cannot act exactly like the type they are proxying. Using a proxy
therefore requires the significant mental overhead of keeping track of
all the corner cases in which the proxy does not act like the type it is
proxying, as well as the hassle of working around those limitation
whenever they come up.
I agree to some extent.
Andrei