Implicit string lit conversion to wstring/dstring

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Mar 14 12:34:08 PDT 2012


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


More information about the Digitalmars-d mailing list