digitalmars.D.learn - Possible bug
- Sergei Nosov (27/27) Mar 25 2013 Hi!
- bearophile (6/10) Mar 25 2013 Some persons have proposed alternative designs, but D is working
- Sergei Nosov (2/12) Mar 25 2013 Thx, is there any good rationale?
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/27) Mar 25 2013 This design allows templated constructors:
- Steven Schveighoffer (14/25) Mar 25 2013 Templated constructors would not be disallowed if you allowed IFTI on =
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (23/50) Mar 25 2013 It would complicate matters: The parameter would be for the constructor
- Steven Schveighoffer (36/90) Mar 25 2013 on
- Sergei Nosov (12/12) Mar 25 2013 Thank you, guys!
- Steven Schveighoffer (27/37) Mar 25 2013 What you have to do is instantiate the template, then call the construct...
- Sergei Nosov (3/30) Mar 26 2013 Thx a lot!
- Steven Schveighoffer (13/28) Mar 25 2013 There really isn't. I have created an enhancement request that you migh...
Hi! This code doesn't compile with dmd v2.062 on Linux_x86_64 <pre> struct test(T) { T *data_; this(T *data) { data_ = data; } } void main() { int *cptr = null; test!int hello = test(cptr); } </pre> Error: dmd test.d test.d(12): Error: struct test.test does not match any function template declaration. Candidates are: test.d(2): test.test(T) test.d(12): Error: struct test.test(T) cannot deduce template function from argument types !()(int*) Everything's fine if I specify parameters explicitly: <pre> test!int hello = test!int(cptr); </pre>
Mar 25 2013
Sergei Nosov:Everything's fine if I specify parameters explicitly: <pre> test!int hello = test!int(cptr); </pre>Some persons have proposed alternative designs, but D is working as currently designed here... Unlike template functions, templated structs don't infer the type. Bye, bearophile
Mar 25 2013
On Monday, 25 March 2013 at 14:12:17 UTC, bearophile wrote:Sergei Nosov:Thx, is there any good rationale?Everything's fine if I specify parameters explicitly: <pre> test!int hello = test!int(cptr); </pre>Some persons have proposed alternative designs, but D is working as currently designed here... Unlike template functions, templated structs don't infer the type. Bye, bearophile
Mar 25 2013
On 03/25/2013 08:11 AM, Sergei Nosov wrote:On Monday, 25 March 2013 at 14:12:17 UTC, bearophile wrote:This design allows templated constructors: struct S // <-- not a template { this(T)(T t) // <-- template { // ... } // ... } The same in C++... AliSergei Nosov:Thx, is there any good rationale?Everything's fine if I specify parameters explicitly: <pre> test!int hello = test!int(cptr); </pre>Some persons have proposed alternative designs, but D is working as currently designed here... Unlike template functions, templated structs don't infer the type. Bye, bearophile
Mar 25 2013
On Mon, 25 Mar 2013 11:31:17 -0400, Ali =C3=87ehreli <acehreli yahoo.com=wrote:This design allows templated constructors: struct S // <-- not a template { this(T)(T t) // <-- template { // ... } // ... } The same in C++...Templated constructors would not be disallowed if you allowed IFTI on = templated structs/classes without templated constructors. When you decompose constructors, they are simply fucntions, and IFTI = exists on functions. The same should be allowed for constructors. There is almost no difference between this: template foo(T){ void foo(T t) {} } and this: struct foo(T){ this(T t) {} } -Steve
Mar 25 2013
On 03/25/2013 12:40 PM, Steven Schveighoffer wrote:On Mon, 25 Mar 2013 11:31:17 -0400, Ali Çehreli <acehreli yahoo.com>wrote:It would complicate matters: The parameter would be for the constructor if the constructor were a template, for the struct otherwise.This design allows templated constructors: struct S // <-- not a template { this(T)(T t) // <-- template { // ... } // ... } The same in C++...Templated constructors would not be disallowed if you allowed IFTI on templated structs/classes without templated constructors.When you decompose constructors, they are simply fucntions, and IFTI exists on functions. The same should be allowed for constructors.I completely agree and that's my point. :) The template parameter list of the constructor should stay with the constructor.There is almost no difference between this: template foo(T){ void foo(T t) {} } and this: struct foo(T){ this(T t) {} }Actually, the latter is a shorthand for this: template S(T) { struct S { T t; this(U)(U) {} } } As you see, T comes from the outer template and U stays with the constructor. It allows the following use: void main() { auto s = S!int(byte.init); }-SteveAli
Mar 25 2013
On Mon, 25 Mar 2013 17:13:58 -0400, Ali =C3=87ehreli <acehreli yahoo.com=wrote:On 03/25/2013 12:40 PM, Steven Schveighoffer wrote: > On Mon, 25 Mar 2013 11:31:17 -0400, Ali =C3=87ehreli <acehreli yaho=o.com> =wrote: > >> This design allows templated constructors: >> >> struct S // <-- not a template >> { >> this(T)(T t) // <-- template >> { >> // ... >> } >> >> // ... >> } >> >> The same in C++... > > Templated constructors would not be disallowed if you allowed IFTI =on> templated structs/classes without templated constructors. It would complicate matters: The parameter would be for the constructo=r =if the constructor were a template, for the struct otherwise.In cases where the struct is templated and the constructor is not, it = would apply to the struct. In cases where the struct is concrete and th= e = constructor is templated, it would apply to the constructor. In the cas= e = where the struct is templated AND the constructor is templated, it would= = require the struct to have an explicit instantiation. This is not complex, nor unintuitive.> When you decompose constructors, they are simply fucntions, and IFT=I> exists on functions. The same should be allowed for constructors. I completely agree and that's my point. :) The template parameter list==of the constructor should stay with the constructor.In the rare cases where the struct and the constructor are templated, it= = will stay with the constructor.> There is almost no difference between this: > > template foo(T){ > void foo(T t) {} > } > > and this: > > struct foo(T){ > this(T t) {} > } Actually, the latter is a shorthand for this: template S(T) { struct S { T t; this(U)(U) {} } }No, it is shorthand for this: template foo(T) { struct foo { this(T t) {} } } Note there is only ONE template type. For your case, the shorthand would be: struct S(T) { this(U)(U u) {} }As you see, T comes from the outer template and U stays with the =constructor. It allows the following use: void main() { auto s =3D S!int(byte.init); }This would be required if both struct and constructor are templated (and= = rightly so). -Steve
Mar 25 2013
Thank you, guys! You made the matters clear to me! It would be an interesting enhancement over C++. Although, Steven, I didn't quite understand what you're suggesting to use in case of "templated-struct-templated-constructor" Explicitly specifying struct parameters is ok. Deducing constructor parameters from arguments is also ok. But what if not all of the constructor parameters may be deduced? E.g. one of them is an int? Would it be a no-no case? or should we merge the lists in one? or should we use two bangs? S!(int, 4)!(byte, 5)(3) ? =)
Mar 25 2013
On Tue, 26 Mar 2013 01:28:03 -0400, Sergei Nosov <sergei.nosov gmail.com> wrote:Thank you, guys! You made the matters clear to me! It would be an interesting enhancement over C++. Although, Steven, I didn't quite understand what you're suggesting to use in case of "templated-struct-templated-constructor" Explicitly specifying struct parameters is ok. Deducing constructor parameters from arguments is also ok. But what if not all of the constructor parameters may be deduced? E.g. one of them is an int? Would it be a no-no case? or should we merge the lists in one? or should we use two bangs? S!(int, 4)!(byte, 5)(3) ? =)What you have to do is instantiate the template, then call the constructor: S!(int, 4).S!(byte, 5)(3) Note that the way templates work in D, a templated struct is really a shortcut for: template S(T) { struct S { ... } } So when you instantiate it, S!(int)(5) is really shorthand for S!(int).S(5). Every template is this way. The shorthand version calls on the "eponymous" member implicitly, that is, the member with the same name as the template. Currently, this only works if there is exactly one member. For example, a function template is really: template foo(T) { void foo(T t) {...} } So doing: foo!(int)(1) is really the same as: foo!(int).foo(1) It's all outlined here: http://dlang.org/template.html search for Implicit Template Properties -Steve
Mar 25 2013
On Tuesday, 26 March 2013 at 05:40:00 UTC, Steven Schveighoffer wrote:What you have to do is instantiate the template, then call the constructor: S!(int, 4).S!(byte, 5)(3) Note that the way templates work in D, a templated struct is really a shortcut for: template S(T) { struct S { ... } } So when you instantiate it, S!(int)(5) is really shorthand for S!(int).S(5). Every template is this way. The shorthand version calls on the "eponymous" member implicitly, that is, the member with the same name as the template. Currently, this only works if there is exactly one member. For example, a function template is really: template foo(T) { void foo(T t) {...} } So doing: foo!(int)(1) is really the same as: foo!(int).foo(1) It's all outlined here: http://dlang.org/template.html search for Implicit Template Properties -SteveThx a lot!
Mar 26 2013
On Mon, 25 Mar 2013 11:11:40 -0400, Sergei Nosov <sergei.nosov gmail.com> wrote:On Monday, 25 March 2013 at 14:12:17 UTC, bearophile wrote:There really isn't. I have created an enhancement request that you might be interested in voting for. http://d.puremagic.com/issues/show_bug.cgi?id=6082 Note that auto is your friend here to avoid the dual-specification of the template: auto hello = test!int(cptr); And you can always create a wrapper function: test!T mktest(T)(T *ptr) { return test!T(ptr);} ... auto hello = mktest(cptr); // no explicit instantiation required -SteveSergei Nosov:Thx, is there any good rationale?Everything's fine if I specify parameters explicitly: <pre> test!int hello = test!int(cptr); </pre>Some persons have proposed alternative designs, but D is working as currently designed here... Unlike template functions, templated structs don't infer the type. Bye, bearophile
Mar 25 2013