7 ms·
Interestingly, C suffers from a somewhat similar ambiguity, where not the results of runtime-at-compile-time but rather type definitions affect the parsing. ht
by nothingmuch 17y ago
Interestingly, C suffers from a somewhat similar ambiguity, where not the results of runtime-at-compile-time but rather type definitions affect the parsing.
http://calculist.blogspot.com/2009/02/c-typedef-parsing-problem.html http://calculist.blogspot.com/2009/02/c-typedef-parsing-prob...
- pmjordan 17y agoIn C++, the problem becomes so bad that the language designers capitulated in some instances, and you have to tell the compiler if something is a type or an identifier. Haven't tested this example, but you get the point: struct test { typedef int bar; }; template <class T> struct foo { typename T::bar x; // if you leave off 'typename', it won't compile }; foo<test> y; y.x = 5; What I don't quite understand is why, if it won't compile in the first place (i.e. there is no ambiguity, just correct or incorrect), you need to specify it in the first place. I suspect it somehow makes compiler implementation easier.
- haberman 17y agoIt's not about making compiler implementations easier -- it's about protecting template authors against having someone write: class MyBadClass { static int bar; }; foo<MyBadClass> y; By writing "typename", the template author can indicate that "T::bar" the template author can indicate that "bar" is expected to be a type, not a variable. This is explained in more detail here: http://pages.cs.wisc.edu/~driscoll/typename.html http://pages.cs.wisc.edu/~driscoll/typename.html.
- pmjordan 17y agoYes, but my argument is that such an instantiation could easily be determined automatically. The declaration T::bar x; makes no sense under any circumstances if T::bar is not a type. Ergo, putting typename in front is redundant.
- haberman 17y agoYes but what if your declaration was: T::bar * x; Now the parse is ambiguous. While the language could say "you only need to use typename if the declaration would otherwise be ambiguous," it's simpler and more consistent to say "all qualified dependent types must use typename."
- haberman 17y agoIn C++ that problem gets worse. To parse: Template<params>::InnerDef * y; ...you have to know whether InnerDef is a type or a number. If it's a type, this is a declaration of a pointer y. If it's a number, it's a multiplication which is then discarded. The problem is that to know whether InnerDef is a type or a number you have to instantiate Template<params>. But C++ templates are Turing-complete: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.3670 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.3...), so performing this instantiation would be undecidable except that C++ defines a recursion depth limit. There's a nice writeup of this problem in the C++ FQA: http://yosefk.com/c++fqa/web-vs-c++.html http://yosefk.com/c++fqa/web-vs-c++.html.