digitalmars.D - Implicit string lit conversion to wstring/dstring
- H. S. Teoh (27/27) Mar 14 2012 Code:
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (8/33) Mar 14 2012 I doubt that such an implicit conversion even exists. You have to prefix...
- =?ISO-8859-1?Q?Alex_R=F8nne_Petersen?= (8/47) Mar 14 2012 Sorry, I lied. Like this:
- H. S. Teoh (10/46) Mar 14 2012 OK, maybe implicit conversion is the wrong word. The compiler is
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (8/52) Mar 14 2012 But then... why not just make it take a dstring? Maybe I'm not following...
- Nick Sabalausky (8/10) Mar 14 2012 Probably because then this becomes an error:
- Steven Schveighoffer (5/7) Mar 14 2012 http://d.puremagic.com/issues/show_bug.cgi?id=4998
- H. S. Teoh (43/52) Mar 14 2012 [...]
- Andrei Alexandrescu (6/18) Mar 14 2012 Aha! This is one of those cases in which built-in magic smells of putrid...
- H. S. Teoh (24/47) Mar 14 2012 [...]
- Andrei Alexandrescu (4/14) Mar 14 2012 Try special casing for the exact types (string, char[] etc), get that
- Timon Gehr (7/52) Mar 14 2012 Use this for now:
- Timon Gehr (6/12) Mar 14 2012 oops.
- H. S. Teoh (10/34) Mar 14 2012 [...]
- H. S. Teoh (36/38) Mar 17 2012 [...]
- H. S. Teoh (48/48) Mar 18 2012 OK, perhaps the previous subject line of the previous post deterred
- Timon Gehr (3/51) Mar 19 2012 This is a bug I have reported some time ago.
- James Miller (17/65) Mar 18 2012 onvertible!K) {}
- Dmitry Olshansky (12/37) Mar 14 2012 How about this (untested)?
- Nick Sabalausky (6/15) Mar 14 2012 That fails to compile when passed a dstring because it matches both
Code: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) T -- He who laughs last thinks slowest.
Mar 14 2012
On 14-03-2012 19:00, H. S. Teoh wrote:Code: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) TI doubt that such an implicit conversion even exists. You have to prefix the string appropriately, e.g.: string s = "foo"; wstring w = w"bar"; dstring d = d"baz"; -- - Alex
Mar 14 2012
On 14-03-2012 19:00, Alex Rnne Petersen wrote:On 14-03-2012 19:00, H. S. Teoh wrote:Sorry, I lied. Like this: string s = "foo"c; (the c is optional) wstring w = "bar"w; dstring d = "baz"d; See: http://dlang.org/lex.html -- - AlexCode: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) TI doubt that such an implicit conversion even exists. You have to prefix the string appropriately, e.g.: string s = "foo"; wstring w = w"bar"; dstring d = d"baz";
Mar 14 2012
On Wed, Mar 14, 2012 at 07:00:35PM +0100, Alex Rønne Petersen wrote:On 14-03-2012 19:00, H. S. Teoh wrote:OK, maybe implicit conversion is the wrong word. The compiler is obviously interpreting func("abc") as func("abc"d) when we declare func(dstring). But when we declare func(S)(S), the compiler deduces "abc" as string and sets S=string. What I want is to force the compiler to deduce S=dstring when I declare func(S)(S) and call it as func("abc"). T -- Дерево держится корнями, а человек - друзьями.Code: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) TI doubt that such an implicit conversion even exists. You have to prefix the string appropriately, e.g.:
Mar 14 2012
On 14-03-2012 19:16, H. S. Teoh wrote:On Wed, Mar 14, 2012 at 07:00:35PM +0100, Alex Rønne Petersen wrote:But then... why not just make it take a dstring? Maybe I'm not following your intent here... Anyway, what Phobos functions tend to do is to set S = string by default and otherwise force people to either pass the string type *or* use the string suffices. -- - AlexOn 14-03-2012 19:00, H. S. Teoh wrote:OK, maybe implicit conversion is the wrong word. The compiler is obviously interpreting func("abc") as func("abc"d) when we declare func(dstring). But when we declare func(S)(S), the compiler deduces "abc" as string and sets S=string. What I want is to force the compiler to deduce S=dstring when I declare func(S)(S) and call it as func("abc"). TCode: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) TI doubt that such an implicit conversion even exists. You have to prefix the string appropriately, e.g.:
Mar 14 2012
"Alex Rnne Petersen" <xtzgzorex gmail.com> wrote in message news:jjqn9f$1iht$1 digitalmars.com...But then... why not just make it take a dstring? Maybe I'm not following your intent here...Probably because then this becomes an error: string s = "abc"; func(s); It's an interesting problem. I'm not aware of a solution. I suppose you'd just have to make it take only dstring and then expect string/wstring vars to be handled by the caller like "func(to!dstring(s))"
Mar 14 2012
On Wed, 14 Mar 2012 14:16:11 -0400, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:What I want is to force the compiler to deduce S=dstring when I declare func(S)(S) and call it as func("abc").http://d.puremagic.com/issues/show_bug.cgi?id=4998 Please vote or contribute your thoughts. -Steve
Mar 14 2012
On Wed, Mar 14, 2012 at 02:44:40PM -0400, Steven Schveighoffer wrote:On Wed, 14 Mar 2012 14:16:11 -0400, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:[...] Ahhh, thanks for pointing this out. That is exactly the problem I'm struggling with. I guess the motivation of my original question wasn't clear. I should say that I ran into this problem in the context of my AA implementation. I've successfully implemented Andrei's suggestion: int[wstring] will now accept wchar[], const(wchar)[], in addition to wstring in .get, .opIndex, etc.. It will implicitly call wchar[].idup when it needs to create a new hash entry. (Ditto with dstring, and with any immutable array key type.) To implement this change, opIndexAssign now looks like this: struct AssociativeArray(Key,Value) { ... void opIndexAssign(K)(in Value v, in K key) if (isCompatWithKey!K) { ... } } The template isCompatWithKey basically checks if K can be implicitly converted to Key, or has an .idup method that returns something that can be implicitly converted to Key. 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. Now you have to write: aa["abc"w] = 123; which isn't the end of the world, I suppose, but it's not very nice, and also breaks existing code that depended on the compiler automatically deducing that typeof("abc")==wstring. T -- There are three kinds of people in the world: those who can count, and those who can't.What I want is to force the compiler to deduce S=dstring when I declare func(S)(S) and call it as func("abc").http://d.puremagic.com/issues/show_bug.cgi?id=4998 Please vote or contribute your thoughts.
Mar 14 2012
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. 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. Andrei
Mar 14 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:+1.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.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
Mar 14 2012
On 3/14/12 2:34 PM, H. S. Teoh wrote: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); }Try special casing for the exact types (string, char[] etc), get that working, and then generalize from there. Andrei
Mar 14 2012
On 03/14/2012 08:34 PM, H. S. Teoh wrote:On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote:Use this for now: void opIndexAssign(K)(in int v, scope K key) if (!is(K==Key) && isCompatWithKey!K) {...} 'in K key'/const(K) key will only IFTI-match a const type. I don't think that is sensible at all, you may want to file a bug report.On 3/14/12 2:01 PM, H. S. Teoh wrote:+1.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.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
Mar 14 2012
On 03/14/2012 09:18 PM, Timon Gehr wrote:Use this for now: void opIndexAssign(K)(in int v, scope K key) if (!is(K==Key) && isCompatWithKey!K) {...}oops. I meant: void opIndexAssign(K)(in Value v, scope K key) if (!is(K==Key) && isCompatWithKey!K) {...}'in K key'/const(K) key will only IFTI-match a const type. I don't think that is sensible at all, you may want to file a bug report.
Mar 14 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:[...] Also, IMHO, this needs to work for array literals in general, not just strings. For example, this should work: int[ubyte[]] aa; aa[[1,2,3]] = 123; The [1,2,3] should be deduced as ubyte[] instead of int[]. T -- Ignorance is bliss... but only until you suffer the consequences!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. 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.
Mar 14 2012
On Wed, Mar 14, 2012 at 02:07:04PM -0500, Andrei Alexandrescu wrote: [...]Aha! This is one of those cases in which built-in magic smells of putrid beef soup.[...] It gets worse than we first thought: void f1(dstring x) { dstring y = x; } void f2()(dstring x) { dstring y = x; } void f2(U)(U x) if (!is(U==string)) { dstring y = x; } void f3(byte[] x) { byte[] y = x; } void f4()(byte[] x) { byte[] y = x; } void f4(U)(U x) if (!is(U==int[])) { byte[] y = x; } void main() { f1("abc"); // OK: "abc" deduced as dstring f2("abc"); // OK: "abc" defaults to string, but f2(U)(U) // declines U==string, so f2()(dstring) is // chosen, and "abc" is deduced as dstring f3([1,2,3]); // OK: [1,2,3] deduced as byte[] f4([1,2,3]); // Error: template test2.f4() does not match any function template declaration // Error: template test2.f4() cannot deduce template function from argument types !()(int[]) } WAT?? So "abc" will match f()(dstring x), but [1,2,3] doesn't match f()(byte[] b)? Upon further investigation: void f5(dstring s) {} void f6()(dstring s) {} void f7(byte[] s) {} void f8()(byte[] s) {} void main() { f5("abc"); // OK f6("abc"); // OK (!) f7([1,2,3]); // OK f8([1,2,3]); // cannot deduce template function from argument types !()(int[]) } WAT? T -- "You know, maybe we don't *need* enemies." "Yeah, best friends are about all I can take." -- Calvin & Hobbes
Mar 17 2012
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
Mar 18 2012
On 03/19/2012 04:40 AM, H. S. Teoh 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. :-( --TThis is a bug I have reported some time ago. Vote here: http://d.puremagic.com/issues/show_bug.cgi?id=7366
Mar 19 2012
On 19 March 2012 16:40, H. S. Teoh <hsteoh 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: =C2=A0 =C2=A0 =C2=A0 =C2=A0int[dstring] aa; =C2=A0 =C2=A0 =C2=A0 =C2=A0aa["abc"] =3D 1; =C2=A0// "abc" implicitly ded=uced as dstringCurrently, 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: =C2=A0 =C2=A0 =C2=A0 =C2=A0opIndexAssign(K)(Value v, K key) if (implicitC=onvertible!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: =C2=A0 =C2=A0 =C2=A0 =C2=A0opIndexAssign(Value v, Key key) {} where Key=3D=3Ddstring, because then the compiler implicitly deduces "abc="as a dstring. In order to fix this, one fix is: =C2=A0 =C2=A0 =C2=A0 =C2=A0// Key=3D=3Ddstring =C2=A0 =C2=A0 =C2=A0 =C2=A0opIndexAssign()(Value v, Key key) { __opIndexA=ssignImpl(v,key); }=C2=A0 =C2=A0 =C2=A0 =C2=A0opIndexAssign(K)(Value v, K key) =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (implicitConver=tible!K && !is(K=3D=3Dstring))=C2=A0 =C2=A0 =C2=A0 =C2=A0{ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0__opIndexAssignImp=l(v,key);=C2=A0 =C2=A0 =C2=A0 =C2=A0} How this works is, when the compiler sees "abc", it first tries to match opIndexAssign(K=3Dstring)(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: =C2=A0 =C2=A0 =C2=A0 =C2=A0void func(byte[] b) {} =C2=A0 =C2=A0 =C2=A0 =C2=A0func([1,2,3]); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2==A0// OKHowever: =C2=A0 =C2=A0 =C2=A0 =C2=A0void func()(byte[] b) {} =C2=A0 =C2=A0 =C2=A0 =C2=A0func([1,2,3]); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2==A0// Does not match templateBecause 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: =C2=A0 =C2=A0 =C2=A0 =C2=A0byte[] b; =C2=A0 =C2=A0 =C2=A0 =C2=A0b =3D [1,2,3]; without compiler changes. :-( --TThis 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
Mar 18 2012
On 14.03.2012 22:00, H. S. Teoh wrote:Code: import std.stdio; version(explicit) { void func(dstring s) { dstring t = s; writeln(t); } } else { void func(S)(S s) { dstring t = s; // line 10 writeln(t); } } void main() { func("abc"); } If version=explicit is set, the program compiles fine. But if not, then the compiler complains: test.d:10: Error: cannot implicitly convert expression (s) of type string to immutable(dchar)[] What do I need to do to make the template version of func trigger implicit conversion of the string lit to dstring? What I'm trying to do is to templatize dstring as well, but still benefit from the string->dstring conversion when instantiated with dstring. (Ditto with implicit conversion to wstring.) THow about this (untested)? void func()(dstring s) { dstring t = s; //... funcImpl(t); } void func(S)(S s) { dstring t = to!dstring(s); //... funcImpl(t); } -- Dmitry Olshansky
Mar 14 2012
"Dmitry Olshansky" <dmitry.olsh gmail.com> wrote in message news:jjqnnj$1j86$1 digitalmars.com...How about this (untested)? void func()(dstring s) { dstring t = s; //... funcImpl(t); } void func(S)(S s) { dstring t = to!dstring(s); //... funcImpl(t); }That fails to compile when passed a dstring because it matches both functions. Adding an "if(!is(S==dstring))" constraint to the second makes it compile, but then func("abc") just calls the second one instead of the first.
Mar 14 2012