Topic: DWP clarification...


Author: Philippe Verdy <100105.3120@compuserve.com>
Date: 1996/03/25
Raw View
Paul Russell aka Rusty <Rusty.Russell@adelaide.maptek.com.au> s'icrit :
> The April DWP, 9.2 paragraph 12:
>
> 12A  static  data  member,  enumerator, member of an anonymous union, or
>   nested type shall not have the same name as its class.
>
> Does this mean immediately nested?  Or nested at all? ie. Is this code
> legal?
>
> struct A
> {
>   struct B
>   {
>     struct A {};
>   };
> };
>
> Also, is there a similar restriction on namespaces?  I couldn't find it
> anywhere...

I think not, because the nested class A is not a member of the
enclosing class A. It will not referenced inside the
enclosing class A directly because it has to explicitly refer
class B to access one of its members (the nested class A would
be explicitly referenced by B::A, provided the nested class
B::A is PUBLICly defined in B, else it would not be accessible
by ::A, which cannot inherit from ::A::B::A ).

However the problem resides in the class B implementation.
What if class B references 'A' ?
I think that the local nested A definition is prioritary
chosen, like in the following case :
  class A;

  class B
  {
    B() {
       A item; // item is of type ::B::A, not ::A
    }
    class A
    {
      ...
    };
  };
In that case the nested class A is a member of B, so any
implementation of B which refers to A refer to ::B::A and
not to ::A. This is to make the class B definition independent
of its context (whever or not there was an outside A
declaration).
Each class constitutes a namespace by its own, and names are
always searched in that namespace before searching any
outside contexts.

So in your case, if a method or initializer of a member of B
references "A", "B::A" will always be referenced at first.
You can override this by using "::A" instead of simply "A"
which refers to "B::A"...

Now what if class B is declared as a friend of the enclosing
class ::A ? E.g. :
class A {
  class B {
  private:
    class A { // this is a private member of B
      friend class ::A; // but now ::A can access it
    };
  };
};
This simply overrides the protected or private
access restriction to public, but it does not change the
namespace extent, so that the same rule applies.

If class ::A::B::A is defined as a private or protected member
of ::A::B, and the ::A::B::A definition does not include class
::A as a friend, there is no access possible from ::A to
::A::B::A which remains unaccessible.
So if ::A implementation uses "A", it means ::A (itself),
but there will be no way to refer to the private ::A::B::A,
unless you add the previous friend declaration.

Is that clear ?
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]