On Tue, 12 Aug 2014 06:21:17 +0000 uri via Digitalmars-d-learn <digitalmars-d-learn@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