On Friday, 20 December 2013 at 17:18:01 UTC, Timon Gehr wrote:
On 12/20/2013 05:40 PM, monarch_dodra wrote:

That's normal, because "T.init" is not an lvalue.

If you need an lvalue, we have `std.traits.lvalueOf!T` which you
can use.

is(typeof((T v){ /+ use v +/ }))

I think this is a lot cleaner.

I dunno. Being forced to declare a scope and a list of variables just to have access to an lvalue instance seems a bit verbose to me. I *think* doing this can lead to issues if done inside an inout context (not certain about this. It's a buggy behavior anywyas, Kenji told me, so not a real argument).

For example:
enum isAssignable(Lhs, Rhs = Lhs) =
    __traits(compiles, lvalueOf!Lhs = lvalueOf!Rhs);

vs

enum isAssignable(Lhs, Rhs = Lhs) =
    __traits(compiles, (Lhs lhs, Rhs rhs){lhs = rhs});

Hum... Actually, I'm not sure which is cleanest. You do bring up a good point. Plus, it solves the whole "initialization issue" we've been having. Why haven't e been using this up to now...?

For example, std.range has a lot of:

template isInputRange(R)
{
    enum bool isInputRange = is(typeof(
    (inout int = 0)
    {
        R r = void;       // can define a range object
        if (r.empty) {}   // can test for empty
        r.popFront();     // can invoke popFront()
        auto h = r.front; // can get the front of the range
    }));
}

The line "R r = void;" has led to problems before. Why haven't we just used:
template isInputRange(R)
{
    enum bool isInputRange = is(typeof(
    (R r, inout int = 0)
    {
        if (r.empty) {}   // can test for empty
        r.popFront();     // can invoke popFront()
        auto h = r.front; // can get the front of the range
    }));
}

Reply via email to