On Saturday 13 September 2014 at 19:29:54 UTC, Andrei Alexandrescu wrote:
On 9/13/14, 1:02 AM, Dmitry Olshansky wrote:
It was just poorly implemented and only for templates. I don't see how
having a different name would help us reach the same effect.

auto ref + static checking + minimal dynamic checking = win

Andrei

When I working on a library AA implementation (druntime#934), I have faced a problem:
I defined special function-factory, which creats AA instance.

auto aaLiteral(Key, Value, T...)(auto ref args)
{
    return AssociativeArray!(Key, Value)(args);
}

struct AssociativeArray(Key, Value)
{
    this(T...)(auto ref T args)
    {
        ...
key = args[0];//schematically, IRL key stored into special Entry structure, which stored into hash-table
    }
    Key key;
}

Now we define struct with postblit, and pass it into aaLiteral.
struct Foo
{
    this(int)
    {
        writeln("C");
    }
    this(this)
    {
         writeln("P");
    }
    ~this()
    {
        writeln("D");
    }
}

auto aa = aaLiteral!(Foo, int)(Foo(1), 2);

This expression expands to the next call chain:
aaLiteral | create Foo, prints C, Foo passed by-value AssociativeArray.this() | pass Foo by ref, because aaLiteral parameter is a l-value key = args[0]; | call postblit, because compiler lost information about what args[0] was a r-value

When human see this code, he see, that we can avoid one postblit and one destructor call and store passed Foo instance directly into "key" field. Have you any idea, how we can resolve this trouble and pass constructed instance without excess postblit calls without/with language changes.

Reply via email to