This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: typename conundrum


On Wed, May 14, 2003 at 01:26:43AM +0100, Kris Thielemans wrote:
 
> I have trouble with modifying my code to get rid of the 'deprecated
> feature' warning related to the typename keyword in C++. I have tested
> this in 3.1 and 3.2 (sorry, nothing more recent yet). Here is my code,
> with comments flagging where the warning appears.

While such questions are better asked on, say, comp.std.c++.moderated
(as there is nothing g++-specific here), the answer is that any name
appearing in a template that is not explicitly declared as a type
IN THAT TEMPLATE is assumed to be an identifier that is not a type.
It doesn't matter if your template is a derived class and the name
is defined as a type in the base class.  You still need typename.
The reason for this is to allow templates to be parsed at the time
they are first declared, and for the parsing to be correct even if
other templates are replaced by specializations.  So, on to your example:
 
> -----------------------------------------
> template <class T>
> class V
> {
> public:
>   typedef T* iterator;
>   iterator begin();
> };

Here T is a type because it's a template parameter, and iterator is a
type because it's a typedef.
 
> template <class T>
> class derived: public V<T>
> {
>   void f();
> };

Here T and V<T> are types because of where they appear.
 
> template <class T>
> void derived<T>::f()
> {
>   // compiler warning in next line:
>   // `typename derived<T>::iterator' is implicitly a typename
>   iterator iter = begin();
>   // next line works, but is awkward
>   typename derived<T>::iterator iter1 = begin();
>   // compiler error in next line:
>   // parse error before `=' token
>   typename iterator iter2 = begin();
> }

Awkward or not, the C++ rule says that if you just type "iterator" the
compiler may assume that it's an identifier, not a type; some compilers
will give you a hard error, not a warning.

I would recommend the style

	typedef typename V<T>::iterator iterator;

or similar, placed once in the class definition.
 
> -----------------------------------------
> Obviously, my 3rd attempt ("typename iterator") was pretty desperate. It
> doesn't even compile with gcc 2.95.2 or 3.0. 

You're taking the wrong approach.  Don't just throw guesses at the compiler
and see what it accepts.  You need a decent reference book.  Stroustrup's
"The C++ Programming Language" (get the 3rd edition, not an older one)
will do, and there are many others.
 
> I understand why the 2nd attempt ("typename derived<T>::iterator") does
> work without warnings. It is the standard thing to do with templated
> arguments (e.g. "typename T::iterator").
> 
> The main questions are thus: 
> - why does the 1st attempt generate a warning? The compiler can easily
> figure out it's a type. 
> - what does the C++ standard has to say about this? (Naively I would
> think that if the 1st isn't correct, than the 3rd should be)
> - how do I fix the 1st attempt without having to resort to the ugly 2nd
> attempt?
> 
> In case my 1st attempt is legal C++, and this issue has been addressed
> in more recent releases of gcc, I would very much appreciate a version
> number where this has been fixed.
> 
> Many thanks
> 
> Kris Thielemans
> Imaging Research Solutions Ltd
> 

-- 
Q. What's more of a headache than a bug in a compiler.
A. Bugs in six compilers.  -- Mark Johnson


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]