On Thursday, 10 January 2013 at 16:42:09 UTC, Tommi wrote:
...which won't compile because T(4) is an rvalue, and according to D, rvalues can't be passed as ref (nor const ref). I don't know which one is flawed, my analogy, or the logic of how D is designed.

My analogy is a bit broken in the sense that methods actually see their designated object as a reference to lvalue even if it is an rvalue. But I don't think that affects the logic of my main argument about scope arguments.

A more strict language logic would be inconvenient.

But, this logic does introduce a discrepancy between non-member operators and member operators in C++ (which D actually side-steps by disallowing non-member operators... and then re-introduces by providing UFCS):

// C++:

struct T
{
    int val = 10;

    T& operator--()
    {
        --val;
        return *this;
    }
};

T& operator++(T& t)
{
    ++t.val;
    return t;
}

int main()
{
    _cprintf("%d\n", (--T()).val); // Prints: 9
    _cprintf("%d\n", (++T()).val); // Error: no known conversion
                                   // from 'T' to 'T&'
    return 0;
}

// D:

import std.stdio;

struct T
{
    int val;

    int get()
    {
        ++val;
        return val;
    }
}

int het(ref T t)
{
    ++t.val;
    return t.val;
}

void main()
{
    writeln(T().get());
    writeln(T().het()); // Error: T(0) is not an lvalue
}

Reply via email to