On Wednesday, 28 September 2016 at 20:23:10 UTC, pineapple wrote:
But using a templated opApply currently breaks type inference in `foreach`, right?

It'd be really nice if that were fixed.

Yeah, it would be nice, but I don't think it's technically possible to fix it. The compiler cannot "guess" the correct opApply instantiation if you don't specify the variable type.

<SEMI-OT> This is due to opApply "inversion of control", so that instead of your code calling other code, other code calls yours. For this reason, I think that ranges are way more straightforward and should be preferred whenever possible </SEMI-OT>

By the way, just to show how opApply can be templated successfully to drive attribute inference:

=======================
struct Foo
{
    uint[2] array;

    int opApply(T : int delegate(ref uint))(scope T dg)
    {
        pragma(msg, "Instantiated with " ~ T.stringof);
                
        int result = 0;
                
        for (int i = 0; i < array.length; i++)
        {
            result = dg(array[i]);
            if (result)
                break;
        }
        return result;
    }
}

void main()
{
    Foo a;

    a.array[0] = 73;
    a.array[1] = 82;

    foreach (ref uint u; a)
    {
        (() @system => u++)();
    }

    foreach (uint u; a)
    {
        import std.stdio;
        writeln(u);
    }
}
=======================

Reply via email to