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

Reply via email to