implicit conversion

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 11 23:37:24 PDT 2014


On Tue, 12 Aug 2014 06:21:17 +0000
uri via Digitalmars-d-learn <digitalmars-d-learn at puremagic.com> wrote:

> Hi,
>
> I'm trying to allow implicit conversions for my own type
> happening. I have the following:
>
> ----
> import std.math;
> import std.traits;
>
> struct S(T)
> if(isFloatingPoint!T)
> {
>      T val;
>      alias val this;
> }
> void main()
> {
>
>      auto s = S!float();
>      assert(isNaN(s));
>      s = 10.0;
>      assert(!isNaN(s));
> }
> ----
>
> But I get a compile time error:
>
> ----
> Error: template std.math.isNaN cannot deduce function from
> argument types !()(S!float), candidates are:
>
> std/math.d(4171):        std.math.isNaN(X)(X x) if
> (isFloatingPoint!X)
> ----
>
> Is there a way I can to do this, maybe opCall/opCast (I tried
> these but failed)?

The problem is that isNaN is now templatized, and its constraint uses
isFloatingPoint, which requires that the type _be_ a floating point type, not
that it implicitly convert to one. So, as it stands, isNAN cannot work with
any type which implicitly converts to a floating point value. Either it will
have to be instantiated with the floating point type - e.g. isNaN!float(s) -
or you're going to have to explicitly cast s to a floating point type.

You can open a bug report - https://issues.dlang.org - and mark it as a
regression, and it might get changed, but the reality of the matter is that
templates don't tend to play well with implicit conversions. It's _far_ too
easy to allow something in due to an implicit conversion and then have it not
actually work, because the value is never actually converted. In general, I
would strongly advise against attempting to give types implicit conversions
precisely because they tend to not play nicely with templates.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list