On 19 March 2012 16:40, H. S. Teoh <hst...@quickfur.ath.cx> wrote: > OK, perhaps the previous subject line of the previous post deterred > people from actually reading the contents. :-( > > Basically, I'm trying to address Andrei's request that this should work > with my AA implementation: > > int[dstring] aa; > aa["abc"] = 1; // "abc" implicitly deduced as dstring > > Currently, for maximum usability, the code allows any type to be > supplied for the key, as long as it can be implicitly converted to the > AA's key type. This is implemented as: > > opIndexAssign(K)(Value v, K key) if (implicitConvertible!K) {} > > However, this causes a problem with dstring and wstring, because a > literal like "abc" defaults to string rather than dstring or wstring, so > when the compiler tries to find a match for opIndexAssign, it sees that > string can't implicitly convert to dstring, so it produces an error. > > This doesn't happen if opIndexAssign was simply: > > opIndexAssign(Value v, Key key) {} > > where Key==dstring, because then the compiler implicitly deduces "abc" > as a dstring. > > In order to fix this, one fix is: > > // Key==dstring > opIndexAssign()(Value v, Key key) { __opIndexAssignImpl(v,key); } > opIndexAssign(K)(Value v, K key) > if (implicitConvertible!K && !is(K==string)) > { > __opIndexAssignImpl(v,key); > } > > How this works is, when the compiler sees "abc", it first tries to match > opIndexAssign(K=string)(Value,K), defaulting "abc" to string, but the > signature constraint declines, so the compiler tries > opIndexAssign()(Value v, dstring key), which matches with "abc" as > dstring. > > This works for string, wstring, and dstring. > > However, the compiler seems to handle numerical literals like [1,2,3] > differently. For example: > > void func(byte[] b) {} > func([1,2,3]); // OK > > However: > > void func()(byte[] b) {} > func([1,2,3]); // Does not match template > > Because of this, it's basically impossible to make literals like [1,2,3] > work with AA's with key type byte[], short[], etc., because [1,2,3] will > never match byte[] in a templated function, and int[] cannot be > implicitly converted to byte[]. So it is impossible to replicate the > implicit conversion in code like: > > byte[] b; > b = [1,2,3]; > > without compiler changes. :-( > > > --T
This sounds like a major bug. At compile time, the compiler should have more than enough information to do the implicit conversion for templates. I haven't looked much at the compiler code, but I assume that there is a semantic pass that does the implicit conversions? Could that be used/copied to where templates get instantiated? -- James Miller