On 7/28/18 6:06 PM, aliak wrote:
On Friday, 27 July 2018 at 14:52:20 UTC, Steven Schveighoffer wrote:
On 7/23/18 2:39 PM, aliak wrote:
Hi,
I'm playing around with an Optional wrapper type. It stores a type T
and a bool that defines whether a value is defined or not:
struct Optional(T) {
T value;
bool defined = false;
this(U : T)(auto ref inout(U) value) inout {
this.value = value;
this.defined = true;
}
}
Don't use inout here. The point of inout on the constructor is to
*transfer* the mutability of the parameter to the struct instance. But
you want to simply copy the type into the struct (an
immutable(Optional!T) is quite useless, no?)
Just use U, not inout(U), and don't put inout on the constructor.
But then it only works for mutable Optional right? Why would an
immutable(Optional!T) be useless? Data can be "forever" empty or a
certain value.
What I meant was that string is actually mutable (the data isn't
mutable, but the string can be re-assigned to another one), so
Optional!string is more useful than immutable(Optional!(char[])). I
shouldn't have said that immutable(Optional!T) is useless, you are
right, and it wouldn't make sense for the defined flag to change there
anyway.
But I see a problem here. string *is* mutable, yet, the parameter is
accepted as inout(char[]). This seems unreasonable, I may want to
preserve the head mutability. I didn't realize IFTI would do this. May
be a bug, but I'm not certain.
But you have it as auto ref, which means since you only sent in rvalues
of strings, you didn't test the ref-ness of it. Indeed, if you do:
string s = "hello";
auto a = defined(s);
you get what you expected!
This doesn't make a whole lot of sense. I wouldn't expect different
types using IFTI this way. I'd recommend filing a bug on inout and IFTI.
There isn't a good way around this...
-Steve