Template constraints: opCmp and opUnary!"++"

monarch_dodra monarchdodra at gmail.com
Fri Dec 20 12:53:29 PST 2013


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
     }));
}



More information about the Digitalmars-d-learn mailing list