On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:
> On 3/14/12 2:01 PM, H. S. Teoh wrote:
> >However, this change broke this code:
> >
> >     AssociativeArray!(wstring,int) aa;
> >     aa["abc"] = 123;        // error: compiler deduces K as string,
> >                             // so isCompatWithKey!K fails: string
> >                             // can't implicitly convert to wstring
> >
> >Whereas before, when opIndexAssign looked like this:
> >
> >             void opIndexAssign(in Value v, in Key key)
> >             {
> >                     ...
> >             }
> >
> >everything worked, because the compiler deduces the type of "abc" as
> >wstring since Key==wstring.
> 
> Aha! This is one of those cases in which built-in magic smells of
> putrid beef soup.

+1.


> I think it's possible to still make this work by beefing up the
> template constraints such that the working signature is selected for
> strings.
[...]

I tried the following, but it still doesn't work properly:

        void opIndexAssign()(in Value v, in Key key)
        {
                __opIndexAssignImpl(v, key);
        }

        void opIndexAssign(K)(in Value v, in K key)
                if (!is(K==Key) && isCompatWithKey!K)
        {
                __opIndexAssignImpl(v, key);
        }

This causes this case to fail:

        AssociativeArray!(wstring,int) aa;
        wchar[] key = "abc"w.dup;
        aa[key] = 123;  // Error: template 
newAA.AA!(immutable(wchar)[],int).AssociativeArray.opIndexAssign() cannot 
deduce template function from argument types !()(int,wchar[])

I don't understand what's happening here.  The condition "!is(K==Key)"
is necessary because otherwise the compiler complains that more than one
template matches the given call, but for some weird reason both
templates vanish from consideration when the condition is put in.


T

-- 
It is the quality rather than the quantity that matters. -- Lucius Annaeus 
Seneca

Reply via email to