[phobos] [D-Programming-Language/phobos] 601c75: Improve parsing error handling

Don Clugston dclugston at googlemail.com
Mon Sep 5 02:20:57 PDT 2011


On 5 September 2011 10:15, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
> On Monday, September 05, 2011 09:46:02 Don Clugston wrote:
>> On 5 September 2011 09:35, Jonathan M Davis <jmdavisProg at gmx.com> wrote:
>> > On Monday, September 05, 2011 00:27:05 Walter Bright wrote:
>> >> On 9/4/2011 11:41 PM, Jonathan M Davis wrote:
>> >> > It still baffles me why anything other than a variable would be an
>> >> > lvalue
>> >>
>> >> *p is also an lvalue.
>> >
>> > Good point, but that's essentially the same as setting the return value
>> > of a function that returns by ref, which essentially is a variable. But
>> > I guess that it does come down to an address more than a variable. What
>> > I really don't get is the temporaries such as when you construct a
>> > struct in place - e.g. S(1) - functioning as lvalues. The result is
>> > that if you have an opEquals which takes const ref like it's supposed
>> > to (or any function which takes a const ref, but opEquals is a good
>> > example), then you can pass it S(1) but not a the result of a function
>> > that returns S(1).
>> >
>> > struct S
>> > {
>> >    bool opEquals(const ref S rhs)
>> >    {
>> >        return val == rhs.val;
>> >    }
>> >
>> >    int val;
>> > }
>> >
>> > S func()
>> > {
>> >    return S(1);
>> > }
>> >
>> > void main()
>> > {
>> >    auto s = S(1);
>> >    assert(s == S(1)); //compiles
>> >    assert(s == func()); //doesn't compile
>> > }
>> >
>> > Obviously, this is a complicated issue, but the situation above is
>> > downright confusing to many people (e.g.
>> > http://stackoverflow.com/questions/6986175/const-ref-and-rvalue-in-d ).
>> > It seems completely inconsistent. Even if C++ treats stuff as lvalues
>> > or not in exactly the same way in D, it's not an issue in the same way
>> > in C++, since const S& will take a temporary in C++, whereas const ref
>> > S won't take a temporary in D.
>>
>> It's not merely confusing. AFAIK there is no possible signature of
>> opEquals which actually works.
>> I think two different issues may be being conflated here, though.
>> I think there's more of a problem with the semantics of 'const ref'
>> and 'auto ref', than with literals being lvalues.
>
> Well, at present you can declare a second version of opEquals which takes its
> argument by value, and it works.

I've never been able to get that to work. Although you can get those
two to work, it fails in other cases. Eg, as in the code below.
Have you been able to do this successfully?

struct S
{
   bool opEquals(const ref S rhs) const
   {
       return val == rhs.val;
   }
   bool opEquals(S rhs) const
   {
       return val == rhs.val;
   }

   int val;
}

S func()
{
   return S(1);
}

void main()
{
   auto s = S(1);
   assert(s == S(1)); //compiles, const ref
   assert(s == func());  // compiles, value
   immutable s2 = S(1);
   assert(s==s2); // fails, ambiguous
}


More information about the phobos mailing list