digitalmars.D.learn - Class template argument deduction from constructor call
- sergk (13/13) Oct 27 2010 class Foo(T) {
- div0 (8/19) Oct 27 2010 It's not a bug.
- =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= (18/40) Oct 27 2010 Why would it only be able to work when there is exactly one
- div0 (19/55) Oct 27 2010 class Foo(T) {
- Jonathan M Davis (12/84) Oct 27 2010 The obvious answer would be that this shouldn't compile because it's amb...
- Steven Schveighoffer (29/84) Oct 27 2010 translates to:
- Steven Schveighoffer (14/22) Oct 27 2010 I should add, it would be ambiguous to do something like this:
- =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= (10/58) Oct 28 2010 Exactly, it should be possible to have consistent behaviour for
- Juanjo Alvarez (2/7) Oct 29 2010 Best match?
class Foo(T) { this(T t) { bar = t; } T bar; } void main() { auto a = new Foo(123); // doesn't work auto b = new Foo!(int)(123); // work, but redundant } Is there any technical limitations preventing this, or its just a compiler bug? -- serg.
Oct 27 2010
On 27/10/2010 20:36, sergk wrote:class Foo(T) { this(T t) { bar = t; } T bar; } void main() { auto a = new Foo(123); // doesn't work auto b = new Foo!(int)(123); // work, but redundant } Is there any technical limitations preventing this, or its just a compiler bug?It's not a bug. I guess it could be a short cut, but it can only ever work when the class has exactly one constructor, which seems a bit of a pointless short cut and adds an unneccassiry corner case to the language spec. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Oct 27 2010
div0 wrote:On 27/10/2010 20:36, sergk wrote:Why would it only be able to work when there is exactly one constructor? Doesn't function overloading work with templates? This works here: void foo(T) (T x) { } void foo(T, U) (T x, U y) { } void main() { foo (3); foo (3, "azerty"); } Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.frclass Foo(T) { this(T t) { bar =3D t; } T bar; } void main() { auto a =3D new Foo(123); // doesn't work auto b =3D new Foo!(int)(123); // work, but redundant } Is there any technical limitations preventing this, or its just a compiler bug?=20 It's not a bug. =20 I guess it could be a short cut, but it can only ever work when the class has exactly one constructor, which seems a bit of a pointless short cut and adds an unneccassiry corner case to the language spec. =20
Oct 27 2010
On 27/10/2010 21:02, "Jérôme M. Berger" wrote:div0 wrote:class Foo(T) { this(T t) { bar = t; } this(string x) { } this(int x) { } T bar; } auto f0 = new Foo("wtf?"); auto f1 = new Foo(42); What's T in any of the above? There's no obvious answer for the first 2 and anything anybody says will be a source of endless arguments and bike shedding. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.ukOn 27/10/2010 20:36, sergk wrote:Why would it only be able to work when there is exactly one constructor? Doesn't function overloading work with templates? This works here: void foo(T) (T x) { } void foo(T, U) (T x, U y) { } void main() { foo (3); foo (3, "azerty"); } Jeromeclass Foo(T) { this(T t) { bar = t; } T bar; } void main() { auto a = new Foo(123); // doesn't work auto b = new Foo!(int)(123); // work, but redundant } Is there any technical limitations preventing this, or its just a compiler bug?It's not a bug. I guess it could be a short cut, but it can only ever work when the class has exactly one constructor, which seems a bit of a pointless short cut and adds an unneccassiry corner case to the language spec.
Oct 27 2010
On Wednesday, October 27, 2010 13:26:21 div0 wrote:On 27/10/2010 21:02, "J=C3=A9r=C3=B4me M. Berger" wrote:The obvious answer would be that this shouldn't compile because it's ambigu= ous.=20 If you force the constructors which conflict with the templated constructor= to be=20 template specializations, then the problem goes away. However, IIRC,=20 unfortunately, at the moment, you can't have a function which has a templat= ed=20 and non-templated version regardless of the number of parameters, though I= =20 believe that there is a bug report on it. =2D Jonathan M Davisdiv0 wrote:=20 class Foo(T) { this(T t) { bar =3D t; } =20 this(string x) { } =20 this(int x) { } =20 T bar; } =20 auto f0 =3D new Foo("wtf?"); auto f1 =3D new Foo(42); =20 What's T in any of the above? =20 There's no obvious answer for the first 2 and anything anybody says will be a source of endless arguments and bike shedding.On 27/10/2010 20:36, sergk wrote:Why would it only be able to work when there is exactly one =20 constructor? Doesn't function overloading work with templates? =20 This works here: void foo(T) (T x) { } =20 void foo(T, U) (T x, U y) { } =20 void main() { =20 foo (3); foo (3, "azerty"); =20 } =20 Jeromeclass Foo(T) { =20 this(T t) { =20 bar =3D t; =20 } T bar; =20 } =20 void main() { =20 auto a =3D new Foo(123); // doesn't work auto b =3D new Foo!(int)(123); // work, but redundant =20 } =20 Is there any technical limitations preventing this, or its just a compiler bug?=20 It's not a bug. =20 I guess it could be a short cut, but it can only ever work when the class has exactly one constructor, which seems a bit of a pointless short cut and adds an unneccassiry corner case to the language spec. =20
Oct 27 2010
On Wed, 27 Oct 2010 16:26:21 -0400, div0 <div0 sourceforge.net> wrote:On 27/10/2010 21:02, "Jérôme M. Berger" wrote:translates to: auto f0 = new Foo!(string)("wtf?"); auto f0 = new Foo!(int)(42); Both of which error, since T can be neither int nor string, or Foo would contain conflicting constructors. Your question is akin to asking why IFTI doesn't work on something like this: T foo(T)(int x); What Jerome was referring to is something like this: class Foo(T) { this(T t) {} this(T t, string x); } which should be unambiguous and completely doable. The thing is, when a templated class is to be instantiated without giving a complete set of template arguments, then it should use IFTI. The decision to try IFTI is not ambiguous, but depending on how you implement the constructors, the overloading can be ambiguous. To answer the OP's question, I don't think there's anything technical restricting the compiler from doing this. I believe it's been proposed several times. If you want to, you can work around the issue by making a wrapper constructor function: Foo!T makeFoo(T)(T t) { return new Foo!T(t); } -Stevediv0 wrote:class Foo(T) { this(T t) { bar = t; } this(string x) { } this(int x) { } T bar; } auto f0 = new Foo("wtf?"); auto f1 = new Foo(42); What's T in any of the above?On 27/10/2010 20:36, sergk wrote:Why would it only be able to work when there is exactly one constructor? Doesn't function overloading work with templates? This works here: void foo(T) (T x) { } void foo(T, U) (T x, U y) { } void main() { foo (3); foo (3, "azerty"); } Jeromeclass Foo(T) { this(T t) { bar = t; } T bar; } void main() { auto a = new Foo(123); // doesn't work auto b = new Foo!(int)(123); // work, but redundant } Is there any technical limitations preventing this, or its just a compiler bug?It's not a bug. I guess it could be a short cut, but it can only ever work when the class has exactly one constructor, which seems a bit of a pointless short cut and adds an unneccassiry corner case to the language spec.
Oct 27 2010
On Wed, 27 Oct 2010 22:10:24 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:To answer the OP's question, I don't think there's anything technical restricting the compiler from doing this. I believe it's been proposed several times. If you want to, you can work around the issue by making a wrapper constructor function: Foo!T makeFoo(T)(T t) { return new Foo!T(t); }I should add, it would be ambiguous to do something like this: class Foo(T, U) { this(T t, U u) {} this(U u, T t) {} } This kind of situation currently doesn't exist in IFTI, since only templates that have exactly one member and it is a function can participate in IFTI. But if the classes are made to work in normal cases, then I think IFTI can be extended to support this kind of thing -Steve
Oct 27 2010
Steven Schveighoffer wrote:On Wed, 27 Oct 2010 16:26:21 -0400, div0 <div0 sourceforge.net> wrote: =20dclass Foo(T) { this(T t) { bar =3D t; } this(string x) { } this(int x) { } T bar; } auto f0 =3D new Foo("wtf?"); auto f1 =3D new Foo(42); What's T in any of the above?=20 translates to: auto f0 =3D new Foo!(string)("wtf?"); auto f0 =3D new Foo!(int)(42); =20 Both of which error, since T can be neither int nor string, or Foo woul=contain conflicting constructors. =20 Your question is akin to asking why IFTI doesn't work on something like=this: =20 T foo(T)(int x); =20 What Jerome was referring to is something like this: =20 class Foo(T) { this(T t) {} this(T t, string x); } =20 which should be unambiguous and completely doable. =20 The thing is, when a templated class is to be instantiated without giving a complete set of template arguments, then it should use IFTI.=20 The decision to try IFTI is not ambiguous, but depending on how you implement the constructors, the overloading can be ambiguous. =20Exactly, it should be possible to have consistent behaviour for template class constructors and template functions: they should both work and fail in similar circumstances. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Oct 28 2010
On Wed, 27 Oct 2010 21:26:21 +0100, div0 <div0 sourceforge.net> wrote:this(T t) { this(string x) { this(int x) {auto f0 = new Foo("wtf?"); auto f1 = new Foo(42);Best match?
Oct 29 2010