typename conundrum
Matt Austern
austern@apple.com
Wed May 14 00:35:00 GMT 2003
On Tuesday, May 13, 2003, at 05:26 PM, Kris Thielemans wrote:
> Hi,
>
> First of all: sorry to post this question! I know there have been
> various emails on this topic before, and even bugs submitted and
> resolved. However, the status of all these reports/bugs is unclear to
> me... Sorry again.
>
> 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.
>
> -----------------------------------------
> template <class T>
> class V
> {
> public:
> typedef T* iterator;
> iterator begin();
> };
>
> template <class T>
> class derived: public V<T>
> {
> void f();
> };
>
> 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();
> }
>
> template derived<int>;
>
> -----------------------------------------
> Obviously, my 3rd attempt ("typename iterator") was pretty desperate.
> It
> doesn't even compile with gcc 2.95.2 or 3.0.
>
> 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.
The sad thing is, it can't. Not according to the C++ Standard, anyway.
The fact that the compiler accepts it at all is a bug/extension (take
your pick). The key is that 'iterator' comes from a base class and
you're using it in a derived class.
It's not a dependent name, in that the bare word 'iterator' doesn't
explicitly depend on a template parameter, so it isn't found in phase
2 name lookup. But it can't be found until the template is instantiated
(the base class might have a specialization that's relevant, and you
can't know that before instantiation), so it also isn't found in phase
1 names lookup. In a standard-conforming compiler it isn't found at
all.
In my opinion, the simplest fix is to put 'using V<T>::iterator'
somewhere
in derived's class definition.
--Matt
More information about the Gcc
mailing list