digitalmars.D.learn - Overloading Based on Constraints
- jmh530 (35/35) Jul 23 2015 I was looking at
- Steven Schveighoffer (15/36) Jul 23 2015 Just so you know, *every* template is tried for every call. So the if
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); }
Jul 23 2015
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
Jul 23 2015