Capturing by reference with "visit" from std.variant

Smaehtin smaehtin at invalid.com
Tue Feb 20 16:20:45 UTC 2018


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


More information about the Digitalmars-d-learn mailing list