On Sun, 05 Dec 2010 00:40:26 -0500, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote:

On 12/4/10 22:36 CST, Steven Schveighoffer wrote:
On Sat, 04 Dec 2010 11:00:58 -0500, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:

On 12/4/10 9:23 AM, Don wrote:
Andrei Alexandrescu wrote:
On 12/4/10 12:42 AM, Don wrote:
Officially, opEquals has to have the signature:

struct Foo {
bool opEquals(const ref Foo x) const {...}
}

This is a compiler bug. For structs there should be no official
implementation of opEquals, opCmp etc. All the compiler needs to worry
about is to syntactically translate a == b to a.opEquals(b) and then
let the usual language rules resolve the call.

Fine, but try to implement a generic type which supports ==.
For example, Tuple in std.typecons.
The only reason that many of the Tuple unit tests pass is that opEquals
never gets instantiated.

I think it should be as follows:

bool opEquals(auto ref inout Tuple rhs) inout {
foreach (i, T; Types) {
if (this[i] != rhs[i]) return false;
}
return true;
}


No no no, inout does not belong here. Use const. inout is only used if
you are returning a portion of the arguments. That should be a hard rule
by the compiler (error).

Fixed:

bool opEquals(auto ref const(Tuple) rhs) const

Then you handle the angry crowds for me please.

Huh? I don't think you understand what I mean. inout only implicitly converts to const. Example:

struct S
{
  bool opEquals(S rhs){return false;}
}

struct T
{
  S s;
  bool opEquals(auto ref inout T rhs) inout {
return s == rhs.s; // error, cannot call S.opEquals(S rhs) with parameters (inout S) inout
  }
}

You gain nothing from making opEquals of Tuple inout vs. const.

IMO all opEquals should be const functions, and the parameter should be const if it is marked as ref, or it contains references.


How can opEquals be defined in a way that it works for structs with
destructors, and also with rvalues?

"auto ref" should be used whenever you want to accept both a value and
an rvalue. For structs with destructors see my other post in this thread.

Unfortunately, "auto ref" is currently implemented wrongly due to a
misunderstanding between Walter and myself. I meant it as a relaxation
of binding rules, i.e. "I'm fine with either an rvalue or an lvalue".
He thought it's all about generating two template instantiations. In
fact auto ref should work when there's no template in sight.

But it must instantiate two functions, no?

No.

How does one call the same
function with by ref or by value?

By always using ref.

I'm totally confused. I thought the point of auto ref was to pass by value if it's an rvalue (since the data is already on the stack). If this is not the case, then why not just make ref work that way? Why wouldn't I mark all my functions as auto ref to avoid being pestered by the compiler?

-Steve

Reply via email to