That's because implicit casts in D are much more strict, then those in C/C++. Such seemingly intuitive cats, e.g. from long to int are not performed due to potential loss of data. Casting from int to uint has the same effect of potential loss of data. Probably, the compile-time versions of those casts could use some checks to enable the casts when the actual value can fit into the new type. In any case, I'd recommend you to specify the type of your literals always, because the next time this kind of thing happens, the bug may be silent (especially with templates, that cast types internally).
On Fri, Oct 21, 2011 at 4:31 AM, Tobias Brandt <tob.bra...@googlemail.com> wrote: > Consider the following program: > > class A(uint N) {} > void foo(uint N)(A!N) {} > > void main() > { > auto a = new A!1; // compiles > foo(new A!1); // error > foo(new A!1u); // compiles > foo(cast(A!1u) A!1) // compiles, but may > // crash at runtime > assert(typeid(new A!1) == typeid(new A!1u)) // compiles, fails at runtime > } > > The second line in main gives the following error: > > Error: cannot implicitly convert expression (new A) of type > test.A!(1).A to test.A!(N).A > > Adding the 'u' makes the code compile without errors. Explicitly > instantiating foo with !1 or !1u does not change anything. > > From the first line, it is clear that instantiating A!1 is not the > problem. Apparently A!1 and A!1u are considered distinct types, > although the template parameter must in both cases be of type uint > and have value 1 and thus be identical. > > What's going on here? >