Re: Overloading Based on Constraints

2015-07-23 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/23/15 5:58 PM, jmh530 wrote:

I was looking at
http://dlang.org/concepts.html
where it discusses overloading templates based on constraints. I wanted
to try to overload a template function with another version that does
everything in place. So basically, one has a return and the other
doesn't. However, when I run the code, it only calls the first function.
The second one is ignored. I tried a number of adjustments, but the only
thing that worked is to re-name the function something else, remove the
U's, and just have it be a void function.


Just so you know, *every* template is tried for every call. So the if 
statements are not dependent on each other. Something I've wanted for a 
long time is an if-else mechanism for template constraints.


What ends up happening is you have to repeat your constraints on every 
overload, but negate the previous ones.


In any case, to your code:




import std.stdio : writeln;
import std.traits;

T test(T)(T x)
 if (isNumeric!(T))
{
 writeln(calling test without void);
 T y = x;
 y += 1;
 return y;
}

U test(T, U)(ref T x)
 if (isNumeric!(T)  is(U == void))


this will NEVER be called via IFTI, because U cannot be determined from 
the parameters. Return type (or how you use the result) does not play 
into IFTI at all.


This is likely why it's never used, because it fails to instantiate.

And note that regular overloading does not work like this. You can't 
overload on return type. Overloading on ref works, but only makes it so 
you can dictate how to handle rvalues vs. lvalues differently.


-Steve


Overloading Based on Constraints

2015-07-23 Thread jmh530 via Digitalmars-d-learn

I was looking at
http://dlang.org/concepts.html
where it discusses overloading templates based on constraints. I 
wanted to try to overload a template function with another 
version that does everything in place. So basically, one has a 
return and the other doesn't. However, when I run the code, it 
only calls the first function. The second one is ignored. I tried 
a number of adjustments, but the only thing that worked is to 
re-name the function something else, remove the U's, and just 
have it be a void function.



import std.stdio : writeln;
import std.traits;

T test(T)(T x)
if (isNumeric!(T))
{
writeln(calling test without void);
T y = x;
y += 1;
return y;
}

U test(T, U)(ref T x)
if (isNumeric!(T)  is(U == void))
{
writeln(calling test with void);
x += 2;
}

void main()
{
int a = 1;
int b = test(a);
writeln(b);
int c = b;
test(c);
writeln(c);
}