www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Issue with template constraints in numeric types

reply data pulverizer <data.pulverizer gmail.com> writes:
Dear all,

I am writing template constraints for different numeric types:

```
import std.stdio: writeln;
import std.traits: isIntegral, isNumeric;


T test(T)(T x, T y)
if(is(T: double) && isNumeric!T)
{
	return x*y;
}


auto test(T)(T x, T y)
if(!is(T: double) && isNumeric!T)
{
	return 5*test!double(x, y);
}


void main()
{
	int x = 2;
	double y = 2.0;
	writeln("int test: ", test(x, x));
	writeln("double test: ", test(y, y));
}
```

returns:

```
int test: 4
double test: 4
```

The same issue occurs when I try using template specializations 
instead. Explanations and suggestions please.

Thank you!

Compiler details:
$ dmd --version
DMD64 D Compiler v2.074.1
Copyright (c) 1999-2017 by Digital Mars written by Walter Bright
Aug 03 2017
next sibling parent data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 3 August 2017 at 12:24:02 UTC, data pulverizer wrote:

 The same issue occurs when I try using template specializations 
 instead. ...
That is T test(T: double)(T x, T y){...} and T test(T)(T x, T y){...} Thanks
Aug 03 2017
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Thursday, 3 August 2017 at 12:24:02 UTC, data pulverizer wrote:
 import std.traits: isIntegral, isNumeric;
Are you familiar with isFloatingPoint? http://dpldocs.info/experimental-docs/std.traits.isFloatingPoint.html
 if(is(T: double) && isNumeric!T)
Keep in mind that T:double here means "if T can implicitly convert to double". Since int can implicitly convert to double too, this case covers both families! You might want to try == instead of : for a more exact match.
Aug 03 2017
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 3 August 2017 at 12:31:00 UTC, Adam D. Ruppe wrote:
 On Thursday, 3 August 2017 at 12:24:02 UTC, data pulverizer 
 wrote:
 import std.traits: isIntegral, isNumeric;
Are you familiar with isFloatingPoint? http://dpldocs.info/experimental-docs/std.traits.isFloatingPoint.html
 if(is(T: double) && isNumeric!T)
Keep in mind that T:double here means "if T can implicitly convert to double". Since int can implicitly convert to double too, this case covers both families! You might want to try == instead of : for a more exact match.
Thank you very much! What about this case: ``` T test(T: double)(T x, T y) { return x*y; } auto test(T)(T x, T y) { return 5*test!double(x, y); } ``` which also gives: ``` int test: 4 double test: 4 ```
Aug 03 2017
parent reply data pulverizer <data.pulverizer gmail.com> writes:
On Thursday, 3 August 2017 at 12:35:08 UTC, data pulverizer wrote:
 What about this case:

 ```
 T test(T: double)(T x, T y)
 {
 	return x*y;
 }

 auto test(T)(T x, T y)
 {
 	return 5*test!double(x, y);
 }
 ```

 which also gives:

 ```
 int test: 4
 double test: 4
 ```
Hmm ... it looks as the specialization `:` operator is working like the constraint `:` operator and doing convertible at least for the floating point case. Is that right?
Aug 03 2017
parent jmh530 <john.michael.hall gmail.com> writes:
On Thursday, 3 August 2017 at 12:49:48 UTC, data pulverizer wrote:
 Hmm ... it looks as the specialization `:` operator is working 
 like the constraint `:` operator and doing convertible at least 
 for the floating point case. Is that right?
They're both doing the same thing as far as I know.
Aug 04 2017