On Friday, 25 January 2013 at 01:57:02 UTC, Jonathan M Davis wrote:
The compiler _has_ to pick either const or ref as having higher precedence. ref was almost certainly chosen as having higher precedence because it avoids a conversion, but also by picking ref, you end up with fewer unnecessary copies, making it the more efficient choice. So, from the standpoint of both type conversions and efficiency, it makes more sense for ref to have precedence over const than the other way around.

The reality of the matter is that regardless of whether const or ref had precedence, you'd still need all 4 overloads or you'd have problems. auto ref and inout can help reduce the number of overloads required, but the function needs to accept all of the type combinations in order to avoid having to convert the type or make unnecessary copies.

Personally that doesn't seem like it makes sense. I know it does logically, but at the same time it seems silly. If you have something as const, why do you need a non-const version?

Example might be if you were to re-write strlen for C, you have a const version but no need for a non-const version as the data will never change. Having multiple ones doing different behavior likely can only get confusing. Say we have the following.

  ///public interface
  int strlen(const char[] input);

  //no public/DDoc interface
  //does what the above does but also swaps upper/lower case
  int strlen(char[] input);

Now when you change something from const to non-const the behavior changes drastically. Even if the Behavior didn't change, there shouldn't be a need for two versions of it for the same name in order for it to work.

There's cases where I've tried to make use of only incorporating a few const/ref differences and yet it fails terribly unless I fill in the other two with unexpected behavior. I see a variable with 'const' and it's I declare 'this variable cannot be changed by me', where as for a function signature it's 'I promise (in good Faith) not to change this'. In these aspects the const should have equal footing as the non-const when determining which to call.

 Here's a older example although I'll have to redo it.

  struct S {
    //move semantics as it's rvalue
    void opAssign(S s);

    //If lvalue, we only want to reference it and
    //make manual updates to this one
    void opAssign(const ref S s);
  }

In this case the opAssign(S) would always be called unless you made the lvalue (or cast it) as const. This personally seems wrong. If const ref had the highest priority the issue goes away, although you cannot have a non-const ref otherwise with the same signature, but why would you need one? It seems to be causing more issues than it helps, kinda like multiple inheritance.

    //with above if const ref was highest
    void opAssign(ref S s); //error, opAssign(const ref S) trumps

If auto ref does get accepted, then it will help alleviate some of the problems, but doesn't feel like all of them will be handled.

Reply via email to