John Fine escreveu:
When f() is defined, the compiler must be informed that B is a template
or it wouldn't know how to parse the following < character.
That's fine, we must live with it... although the most common case (i.e.
B<int>, and not 'B < int') isn't what the compiler considers by default,
even if 'B < int' is ill-defined. That must be something about syntax
parsing time vs. semantic analysis time.
Does typename in your example qualify type (not B)? Is the :: after
B<int> the thing that tells the compiler B<int> can't be a function?
It seems that the '::' tells the compiler that what precedes it is a
type (when the token is followed by another ::), so the 'typename'
qualifier is only to disambiguate the last token.
My rant about 'typename' is that we have to tell the compiler that we're
dealing with types even if it makes no sense for it to be a value. That
is, the following code should be valid:
template <class T> T::other_type function(T::type x)
{
T::type temp = x;
return static_cast<T::other_type>(temp);
}
But the standard requires that all T::* should be prefixed by
'typename'. It makes an exception, tough. Is when we specify a base
class list, which have to be a type. But why not in other cases?
Anyway, my suggestion is to be a little nicer to whatever programmer
will work on this code after you. Make more use of typedef to clarify
the construction.
I usually do that, but I wanted to prove a (wrong) point in my example,
the example was contrived on purpose.
Regards,
rod