Capturing by reference with "visit" from std.variant

Smaehtin smaehtin at invalid.com
Tue Feb 20 21:53:05 UTC 2018


On Tuesday, 20 February 2018 at 16:20:45 UTC, Smaehtin wrote:
> On Tuesday, 20 February 2018 at 16:15:56 UTC, Radu wrote:
>> On Tuesday, 20 February 2018 at 16:01:11 UTC, Smaehtin wrote:
>>> I'm trying to understand why the following doesn't work:
>>>
>>> import std.stdio;
>>> import std.variant;
>>>
>>> void main()
>>> {
>>>     Algebraic!(string, int) test = "Test";
>>>
>>>     test.tryVisit!(
>>>         (ref string s) { s = "Why does this not work?"; }
>>>     );
>>>
>>>     writeln(test);
>>> }
>>>
>>> But this works fine:
>>> *test.peek!string = "Works fine";
>>>
>>> As far as I can tell, the "visit" template expands to 
>>> something that ends up calling my handler like this:
>>> if (auto ptr = variant.peek!T)
>>> {
>>>     handler(*ptr);
>>> }
>>>
>>> But seeing as the handler in my case takes a reference, 
>>> shouldn't that work just fine? What am I missing?
>>
>> Your lambda is called, but you can't change the variant value 
>> trough that reference.
>>
>> Test with:
>>
>> import std.stdio;
>> import std.variant;
>>
>> void main()
>> {
>>     Algebraic!(string, int) test = "Test";
>>
>>     test.tryVisit!(
>>         (ref string s)
>>         {
>>             writeln("Why does this work? ", s);
>>         }
>>     );
>>
>>     writeln(test);
>> }
>>
>>
>> You should get:
>>
>> Why does this work? Test
>> Test
>
> Then my question is: Why can't I change the variant through the 
> reference in the lambda?
> Seeing as this works just fine:
>
> void main()
> {
>     Algebraic!(string, int) test = "Test";
>     changeIt(*test.peek!string);
>
>     writeln(test);
> }
>
> void changeIt(ref string s)
> {
>     s = "Changed";
> }
>
> Prints: Changed

Okay, so I realized this happens because the variant parameter is 
getting passed down to the "visitImpl" function by value.

Wouldn't it make sense to pass the arguments using "auto ref" in 
this case?
This is the code I'm talking about: 
https://github.com/dlang/phobos/blob/9021bd36b97d247cba1def9ce12eca64efee61a5/std/variant.d#L2170

Changing it to "auto ref" would allow capturing by reference in 
the handlers, but I'm not really sure if it would have any 
negative side-effects.


More information about the Digitalmars-d-learn mailing list