Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
For those who don't know what typename does or why it's in the
language (or haven't heard of it), I'll provide a quick overview. If
you know, skip ahead four paragraphs
template
void foo()
{
vector::iterator * x;
...
}
The line I'll be talking about is the one that looks like it should be
a declaration. It's pretty clear that the programmer intends this to
be a declaration of a variable called x whose type is a pointer to an
iterator object, where iterator is found in the scope vector.
However, the compiler is (depending how you look at it) either
stupider or smarter than the programmer: it knows that there could be
a specialization of the vector template for whatever T is finally used
where iterator is a static variable. And who knows, maybe there's a
global x somewhere. In that case, that line is a expression that
multiplies the class static variable called iterator with the global
variable x.
The problem arises anytime you have what's called a dependent
qualified type. The "dependent" part (in the context of C++) means
that it depends on a template parameter. For instance, T, T::iterator,
and vector are all dependent names. The "qualified" part
means that it's not just an undecorated name; it has a "::" in
it. (See below for complications on this rule.)
Any time (almost...) there is a dependent qualified name, C++ requires
you to use typename. So the line above should be changed to "typename
vector::iterator * x"
[RESUMING]
So the presence of typename is an unfortunate consequence of the
syntax/semantics of templates. However, even given that it's here,
it's WAY WAY too complicated.
Here is what I think the C++ committee should have chosen for the
rules for typename:
1. before dependent qualified types, typename is required
2. before other types, typename is optional
I can think of no parsing or other problems this would create. I
posted a query about this to comp.lang.c++ and comp.lang.c++.moderated
a bit ago and received no response, so I'm not sure of it; so if you
can come up with something I'd be glad to hear it.
But here are the ACTUAL typename rules:
1. Before unqualified types (dependent or not), typename is
prohibited.
2. Outside of a template declaration, typename is prohibited.
3. Inside a template declaration, typename is optional before
qualified but nondependent names. (E.g. both 'typename
vector::iterator' and just 'vector::iterator'
are legal.) However, it should probably be noted that an explicit
specialization of a template is NOT itself a template, and so use
of typename falls under rule 2, not this one.
4. Before a qualified dependent type, typename is required, except
that when naming a base class in the base-specifier or a type in a
constructor initializer list, typename is prohibited.
5. The requirement to use typename is transitive. For instance, if you
do 'typedef typename T::iterator T_iterator', you still have to say
'typename T_iterator'. I can think of no reason for this rule.
WAY WAY WAY too complicated, especially the addendum to rule 3, the
exceptions in rule 4, and the entire rule 5.