Topic: Nesting scope resolution


Author: nathan@pact.srf.ac.uk (Nathan Sidwell)
Date: 1996/02/10
Raw View
Is the line tagged //B legal?

class One
{
  unsigned  scalar;
public:
  void func(int);
};
class Two : public One
{
protected:
  typedef One Parent;
};
class Three : public Two
{
protected:
  typedef Two Parent;
public:
  void func(int);
};

void Three::func(int i)
{
  One::func(i);                 //A
  Parent::Parent::func(i);      //B
}

I believe lines A and B are equivalent, but some compilers say yes and some
say no. Visual C++, Borland C++ and cfront reject it. G++ and
SGI C++ accept it.

The construction Parent::Parent::func seems a natural way of getting
at the grandparent methods, without actually knowing the name of the
grandparent class.

The draft ANSI standard has this to say

5.1 defines primary expressions, one of which is an id-expression,

id-expression:
 unqualified-id
 qualified-id

qualified-id:
 nested-name-specifier template<opt> unqualified-id

unqualified-id:
 identifier
 ...

a function call is a postfix expression (5.2), which is

postfix-expression:
 primary-expression
 postfix-expression(expression-list<opt>)
 ...

the nested-name-specified is defined in 7.3.1.1

nested-name-specifier:
 class-or-namespace-name :: nested-name-specifier<opt>

class-or-namespace-name:
 class-name
 namespace-name

it also adds (para 3) that 'The search of a name after a :: locates only named
members of a namespace or class.'

So the expression 'Parent::Parent::func(i)' looks like a
postfix-expression constructed of
primary-expression['Parent::Parent::func'] ( expression-list['i'] )

the primary-expression 'Parent::Parent::func'
looks like a qualified-id of
nested-name-specifier['Parent::Parent::'] unqualified-id[func]

and the nested-name-specifier 'Parent::Parent::' is
class-or-namespace-name['Parent'] :: nested-name-specifier['Parent::']

of which the nested-name-specifier is again
class-or-namespace-name['Parent'] ::

now the question is, is Parent (a typedef) considered a class-name?

section 7.1.3 has this to say about typedefs. 'A typedef-name is thus
a synonym for another type'. Classes are definatly types, so Parent is
a synonym for a class. Para 3 of 7.3.1.1 tells us which typedef to use
after the respective ::. And of course, if Parent wasn't considered a
class-name, I wouldn't be able to write the simple Parent::func, to
get a superclass's method (and we know that works).

QED

Another way of looking at it is that inside a class member function,
member names have an implicit '<ClassName>::' prepended to them.
so writing Parent::func() (which is definiatly ok) is shorthand for
Three::Parent::func(), which isn't a million miles from what I've actually
written.

So which is right?

nathan

--
Nathan Sidwell                         Holder of the Xmris home page
Chameleon Architecture Group at SGS-Thomson, formerly Inmos
http://www.pact.srf.ac.uk/~nathan/                  Tel 0117 9707182
nathan@inmos.co.uk or nathan@bristol.st.com or nathan@pact.srf.ac.uk
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  Moderation policy:
  http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/02/12
Raw View
nathan@pact.srf.ac.uk (Nathan Sidwell) writes:

>Is the line tagged //B legal?

Yes.

Your analysis is correct, IMHO, although not quite complete.
The answer to the question you ask

>now the question is, is Parent (a typedef) considered a class-name?

is yes - the missing piece of the puzzle is 9.1[class.name]/5, which
says "A typedef name which names a class is a class-name".

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  Moderation policy:
  http://reality.sgi.com/employees/austern_mti/std-c++/policy.html. ]