Re: Overload resolution (value vs reference)

2012-10-22 Thread m0rph

Thanks for explanation!


Re: Overload resolution (value vs reference)

2012-10-22 Thread Era Scarecrow
On Sunday, 21 October 2012 at 22:47:00 UTC, Jonathan M Davis 
wrote:



http://dlang.org/function.html#function-overloading

The big thing to remember here is that constness matters more 
than refness when overloads are chosen, so if you want refness 
to matter when choosing an overload, then the constness of the 
overloads must match, and if there's ever a question between 
const and non-const, it's the constness of the argument being 
passed in which wins (e.g. if you have ref T and const ref T, 
then which one gets called depends on whether the argument is 
const or not).


 There any word on if this was going to change? I'm meaning 
towards structs/classes with const preference vs non-const 
preferences. I recall a while back while trying to make copy/move 
functions and I had to completely duplicate the functions so it 
would use the right versions.


Re: Overload resolution (value vs reference)

2012-10-22 Thread Jonathan M Davis
On Monday, October 22, 2012 22:54:44 Era Scarecrow wrote:
 On Sunday, 21 October 2012 at 22:47:00 UTC, Jonathan M Davis
 
 wrote:
  http://dlang.org/function.html#function-overloading
  
  The big thing to remember here is that constness matters more
  than refness when overloads are chosen, so if you want refness
  to matter when choosing an overload, then the constness of the
  overloads must match, and if there's ever a question between
  const and non-const, it's the constness of the argument being
  passed in which wins (e.g. if you have ref T and const ref T,
  then which one gets called depends on whether the argument is
  const or not).
 
 There any word on if this was going to change? I'm meaning
 towards structs/classes with const preference vs non-const
 preferences. I recall a while back while trying to make copy/move
 functions and I had to completely duplicate the functions so it
 would use the right versions.

AFAIK, there are no plans to change it. I don't think that it's even been 
suggested.

For the most part though, you can just have the non-ref version call the ref 
version as long as there's a ref version with the same constness, so even if 
you have to duplicate the function, you don't have to duplicate its body. You 
might be stuck with some duplication between the const and non-const overloads 
though if you have all 4 of them.

- Jonathan M Davis


Re: Overload resolution (value vs reference)

2012-10-22 Thread Era Scarecrow
On Monday, 22 October 2012 at 21:58:04 UTC, Jonathan M Davis 
wrote:
AFAIK, there are no plans to change it. I don't think that it's 
even been suggested.


 I thought I suggested it back for a different order of 
preferences. Basically boils down to accepting the const ones 
over the non-const whenever applicable and possible. Quite 
annoying that it was accepting non-const copy over const ref for 
the purposes I was going for.


For the most part though, you can just have the non-ref version 
call the ref version as long as there's a ref version with the 
same constness, so even if you have to duplicate the function, 
you don't have to duplicate its body. You might be stuck with 
some duplication between the const and non-const overloads 
though if you have all 4 of them.


 Yeah I know... I guess best practice is to offer all const or 
non-const of particular function names/uses, but that doesn't 
always want to work. Let's see how did that go...


 struct S {
   ref S opAssign(S s);   //move. TDPL pg. 257-259
   ref S opAssign(const ref S s); //copy (almost postblitz)

/* as of current, only the 'move' is always used unless the 
struct is actually const. inout isn't applicable I think. I'm 
promising not to change the input on the copy, and the move can't 
be const (if there's any addressing to transfer). I consider the 
reference the important distinction, yet the non-const is always 
called/preferred */


   ref S opAssign(const S s); //duplicate(s) of above in reverse
   ref S opAssign(ref S s);   //best match works better now
 }


Re: Overload resolution (value vs reference)

2012-10-21 Thread Jonathan M Davis
On Sun, 2012-10-21 at 19:01 +0200, m0rph wrote:
 How does compiler selects the proper function among overloaded
 functions which differ only in the way the argument is passed (by
 reference or by value)? Is there a way, to control this behavior?
 
 Result of execution of the test code:
 passed by value: 8
 passed by value: 3
 passed by value: Foo(10)
 
 
 Test code:
 
 import std.stdio;
 
 struct Foo {
   int value;
 }
 
 void f(T)(T foo)
 {
   writeln(passed by value: , foo);
 }
 
 void f(T)(const ref T foo)
 {
   writeln(passed by reference: , foo);
 }
 
 void main()
 {
   // 8 is a r-vlaue, so it's passed by value
   f(8);
 
   // i is a l-value, it's passed by value and it's ok
   int i = 3;
   f(i);
 
   // foo is a l-value, it's passed by value again, but if
 structure will be big enough it'll be ineffective
 
   auto foo = Foo();
   foo.value = 10;
   f(foo);
 }
 

http://dlang.org/function.html#function-overloading

The big thing to remember here is that constness matters more than
refness when overloads are chosen, so if you want refness to matter when
choosing an overload, then the constness of the overloads must match,
and if there's ever a question between const and non-const, it's the
constness of the argument being passed in which wins (e.g. if you have
ref T and const ref T, then which one gets called depends on whether the
argument is const or not).

As your code stands, if it were

void f(T)(T foo)
{
f(foo);
}

void f(T)(const ref T foo)
{
//...
}

you would get an infinite loop when passing an rvalue to f, whereas

void f(T)(const T foo)
{
f(foo);
}

void f(T)(const ref T foo)
{
//...
}

would not.

- Jonathan M Davis