Thread overview
Issue with template constraints in numeric types
Aug 03, 2017
data pulverizer
Aug 03, 2017
data pulverizer
Aug 03, 2017
Adam D. Ruppe
Aug 03, 2017
data pulverizer
Aug 03, 2017
data pulverizer
Aug 04, 2017
jmh530
August 03, 2017
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

August 03, 2017
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
August 03, 2017
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.
August 03, 2017
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
```


August 03, 2017
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?
August 04, 2017
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.