D - Irritating template inconsistency
- Matthew (32/32) Apr 20 2004 D provides for the programmer to omit the type within a template
- Walter (7/39) Apr 20 2004 because
- Derek Parnell (9/58) Apr 20 2004 Walter,
- Walter (11/18) Apr 21 2004 is
- Matthew (7/55) Apr 20 2004 message.
D provides for the programmer to omit the type within a template instantiation, if there is only one type in the template, and it has the same name as the template. This is provided as a convenience (AFAIK). Consider the following code: template Thing(T) { class Thing {} } template Thing2(T) { class Thing2 {} class X {} } int main() { alias Thing!(int) thing_int_t; alias Thing2!(int).Thing2 thing2_int_t; alias Thing!(int).Thing thing_int_2_t; // no property 'Thing' for type 'Thing' return 0; } The first instantiation does not require anything after the "!(int)" because there is only one type - the class Thing - within the Thing template. The second instantiation does require the full qualification, because there are two types within the template. The third instantiation is an error, and gives a misleading error message. Is this intended behaviour? It seems unnecessarily inconsistent, and is very irritating when one is developing template code and moving things around a lot, as the client code has to be changed every time.
Apr 20 2004
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c63vmm$ju5$1 digitaldaemon.com...D provides for the programmer to omit the type within a template instantiation, if there is only one type in the template, and it has the same name as the template. This is provided as a convenience (AFAIK). Consider the following code: template Thing(T) { class Thing {} } template Thing2(T) { class Thing2 {} class X {} } int main() { alias Thing!(int) thing_int_t; alias Thing2!(int).Thing2 thing2_int_t; alias Thing!(int).Thing thing_int_2_t; // no property 'Thing' for type 'Thing' return 0; } The first instantiation does not require anything after the "!(int)"becausethere is only one type - the class Thing - within the Thing template. The second instantiation does require the full qualification, becausethereare two types within the template. The third instantiation is an error, and gives a misleading error message. Is this intended behaviour? It seems unnecessarily inconsistent, and isveryirritating when one is developing template code and moving things around a lot, as the client code has to be changed every time.Yes, it is intended. You can avoid the issue, though, by adding a dummy declaration in the template.
Apr 20 2004
On Tue, 20 Apr 2004 17:26:13 -0700, Walter wrote:"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c63vmm$ju5$1 digitaldaemon.com...Walter, what is your reason for this behaviour. Not that I'm suggesting anything is wrong or otherwise, just curious. I guess I'm hoping that it wasn't an arbitrary or "convenient" decision, but instead one based on sound reasoning. -- Derek 21/Apr/04 11:02:50 AMD provides for the programmer to omit the type within a template instantiation, if there is only one type in the template, and it has the same name as the template. This is provided as a convenience (AFAIK). Consider the following code: template Thing(T) { class Thing {} } template Thing2(T) { class Thing2 {} class X {} } int main() { alias Thing!(int) thing_int_t; alias Thing2!(int).Thing2 thing2_int_t; alias Thing!(int).Thing thing_int_2_t; // no property 'Thing' for type 'Thing' return 0; } The first instantiation does not require anything after the "!(int)"becausethere is only one type - the class Thing - within the Thing template. The second instantiation does require the full qualification, becausethereare two types within the template. The third instantiation is an error, and gives a misleading error message. Is this intended behaviour? It seems unnecessarily inconsistent, and isveryirritating when one is developing template code and moving things around a lot, as the client code has to be changed every time.Yes, it is intended. You can avoid the issue, though, by adding a dummy declaration in the template.
Apr 20 2004
"Derek Parnell" <derek psych.ward> wrote in message news:13z4hgc9kgxng$.1jahjei5gnd6s$.dlg 40tude.net...isYes, it is intended. You can avoid the issue, though, by adding a dummy declaration in the template.Walter, what is your reason for this behaviour. Not that I'm suggesting anythingwrong or otherwise, just curious. I guess I'm hoping that it wasn't an arbitrary or "convenient" decision, but instead one based on sound reasoning.The symbol table lookups needed to be unambiguous. Therefore, a rule is required to say in what scope a symbol is in. Having it in both scopes and trying to guess what the programmer meant leads to trouble like the wretched tag name space in C++. I'd rather have a simple rule that is easilly explained that may lead to minor aggravation on occaision, than a complicated rule that is hard to explain that mostly works right until it doesn't and somebody starts up a "D Bug of the Month" column <g>.
Apr 21 2004
"Walter" <walter digitalmars.com> wrote in message news:c64ffb$1ehd$2 digitaldaemon.com..."Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c63vmm$ju5$1 digitaldaemon.com...message.D provides for the programmer to omit the type within a template instantiation, if there is only one type in the template, and it has the same name as the template. This is provided as a convenience (AFAIK). Consider the following code: template Thing(T) { class Thing {} } template Thing2(T) { class Thing2 {} class X {} } int main() { alias Thing!(int) thing_int_t; alias Thing2!(int).Thing2 thing2_int_t; alias Thing!(int).Thing thing_int_2_t; // no property 'Thing' for type 'Thing' return 0; } The first instantiation does not require anything after the "!(int)"becausethere is only one type - the class Thing - within the Thing template. The second instantiation does require the full qualification, becausethereare two types within the template. The third instantiation is an error, and gives a misleading erroraIs this intended behaviour? It seems unnecessarily inconsistent, and isveryirritating when one is developing template code and moving things aroundWhat's the rationale? It doesn't make sense to me. And your solution smacks of a C++ hack. Isn't this a modern language designed from the off to avoid crappy hacks?lot, as the client code has to be changed every time.Yes, it is intended. You can avoid the issue, though, by adding a dummy declaration in the template.
Apr 20 2004
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c64i8l$1j2g$2 digitaldaemon.com...What's the rationale? It doesn't make sense to me. And your solutionsmacksof a C++ hack. Isn't this a modern language designed from the off to avoid crappy hacks?It's a worse hack to have the symbol appear in two scopes. Consider: template Foo(T) { class Foo { int Foo; } } Now we do: Foo!(int).Foo What are we referring to? class Foo or int Foo?
Apr 21 2004
"Walter" <walter digitalmars.com> wrote in message news:c65dof$314c$2 digitaldaemon.com..."Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c64i8l$1j2g$2 digitaldaemon.com...Well, this is where I could comment that we should be using the :: operator ... I take your point with the given example, but I would then suggest that the short-circuit version be dropped. Since there's still the "!(...)' gunk needed, why not just incline people to use aliases in all cases. I would prefer the consistency, as I'm finding this the most vexing part of my use of templates, and not in the least "minor aggravation on occasion".What's the rationale? It doesn't make sense to me. And your solutionsmacksof a C++ hack. Isn't this a modern language designed from the off to avoid crappy hacks?It's a worse hack to have the symbol appear in two scopes. Consider: template Foo(T) { class Foo { int Foo; } } Now we do: Foo!(int).Foo What are we referring to? class Foo or int Foo?
Apr 21 2004
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c65enm$129$2 digitaldaemon.com...Well, this is where I could comment that we should be using the ::operator ...I take your point with the given example, but I would then suggest thattheshort-circuit version be dropped. Since there's still the "!(...)' gunkneeded,why not just incline people to use aliases in all cases. I would prefertheconsistency, as I'm finding this the most vexing part of my use oftemplates, andnot in the least "minor aggravation on occasion".The short circuit version is there because people simply did not like the: Foo!(int).Foo construct for one member templates, and I didn't either.
Apr 21 2004
"Walter" <walter digitalmars.com> wrote in message news:c66f9s$1qqk$2 digitaldaemon.com..."Matthew" <matthew.hat stlsoft.dot.org> wrote in message news:c65enm$129$2 digitaldaemon.com...Me either. But I like the inconsistency less. Since alias will be a well-used feature with templates anyway, why not remove the confusing/annoying inconsistency?Well, this is where I could comment that we should be using the ::operator ...I take your point with the given example, but I would then suggest thattheshort-circuit version be dropped. Since there's still the "!(...)' gunkneeded,why not just incline people to use aliases in all cases. I would prefertheconsistency, as I'm finding this the most vexing part of my use oftemplates, andnot in the least "minor aggravation on occasion".The short circuit version is there because people simply did not like the: Foo!(int).Foo construct for one member templates, and I didn't either.
Apr 21 2004