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 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


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