Topic: introduction of base-class names into derived classes' scopes


Author: Michael Norrish <michael.norrish@nicta.com.au>
Date: Fri, 25 May 2007 10:59:24 CST
Raw View
g++ rejects the following

----------------------------------------------------------------------
namespace m1 {
   class D1 {
   public:
     int x;
   };
}

namespace m2 {
   class D1 {
   public:
     int z;
   };
}

class D2 : public m1::D1, public m2::D1  {
public:
   int y;
};

D2 d;

int v = d.D1::x;
----------------------------------------------------------------------

saying

   error: D2::D1 has not been declared

(not a great error message).

But if I have D2 inherit only from m1::D1, then the program is
accepted.   However, in this case, I expected to have to write

   int v = d.m1::D1::x;

Unfortunately, I didn't find much in the standard to enlighten me.  In
particular, there doesn't seem to be any language stating that the
unqualified names of base classes are inserted into the scope of the
derived class.  In 10.2 para 1, it says that for qualified ids, name
lookup begins in the scope of the nested-name-specifier.  In other
words, when looking at

   d.D1::x

we should look for an x in the scope of D1.  Of course, there is no D1
in the global scope where v is being declared.

In 3.4.5 para 4, there's language about looking up the name D1 in the
class scope, and in the global scope, and requiring that if both
provide matching names, that they refer to the same entity.  If we
knew that D1 was in D2's scope, that'd be fine (as D1 certainly isn't
in the broader scope).

If it isn't already there, it seems as if there needs to be language
stating that the rightmost component of a base class's qualified name
should be inserted into the derived class's scope, and that if the
same name is thus inserted more than once, then the name is removed...

Or perhaps g++ is just wrong?

Regards,
Michael.

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: greghe@pacbell.net (Greg Herlihy)
Date: Sat, 26 May 2007 06:08:38 GMT
Raw View
On 5/25/07 9:59 AM, in article 4656878c@clarion.carno.net.au, "Michael
Norrish" <michael.norrish@nicta.com.au> wrote:

> g++ rejects the following
>=20
> ----------------------------------------------------------------------
> namespace m1 {
>    class D1 {
>    public:
>      int x;
>    };
> }
>=20
> namespace m2 {
>    class D1 {
>    public:
>      int z;
>    };
> }
>=20
> class D2 : public m1::D1, public m2::D1  {
> public:
>    int y;
> };
>=20
> D2 d;
>=20
> int v =3D d.D1::x;
> ----------------------------------------------------------------------
>=20
> saying
>=20
>    error: D2::D1 has not been declared
>=20
> (not a great error message).

The actual problem is that "D1" is an ambiguous base class of D2 (because=
 D2
inherits from two different classes named "D1" - neither of which inherit=
s
from the other).
=20
> But if I have D2 inherit only from m1::D1, then the program is
> accepted.   However, in this case, I expected to have to write
>=20
>    int v =3D d.m1::D1::x;

It's the other way around. When D2 inherits from two different D1 classes=
,
the program must specify the "m1" namespace in order to disambiguate the
name "D1" in the assignment to v. Of course, in either case the assignmen=
t
could eliminate the D1 qualification completely:

     int v =3D  d.x;
=20
> Unfortunately, I didn't find much in the standard to enlighten me.  In
> particular, there doesn't seem to be any language stating that the
> unqualified names of base classes are inserted into the scope of the
> derived class. =20

See =A710/1:

"Unless redefined in the derived class, members of a base class are also
considered to be members of the derived class. ...Inherited members can b=
e
referred to in expressions in the same manner as other members of the
derived class, unless their names are hidden or ambiguous."

> In 10.2 para 1, it says that for qualified ids, name
> lookup begins in the scope of the nested-name-specifier.  In other
> words, when looking at
>=20
>    d.D1::x
>=20
> we should look for an x in the scope of D1.  Of course, there is no D1
> in the global scope where v is being declared.

The compiler first needs to resolve the name "D1" before it may look for =
an
"x" within its scope. Since the name D1 is ambiguous, the search fails at
that point. Therefore, the fact that only one of D2's "D1" base classes h=
as
a member named "x" - does not matter.

Greg

=20

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Sun, 27 May 2007 17:00:22 GMT
Raw View
Greg Herlihy ha scritto:
> On 5/25/07 9:59 AM, in article 4656878c@clarion.carno.net.au, "Michael
> Norrish" <michael.norrish@nicta.com.au> wrote:
>=20
>> Unfortunately, I didn't find much in the standard to enlighten me.  In
>> particular, there doesn't seem to be any language stating that the
>> unqualified names of base classes are inserted into the scope of the
>> derived class. =20
>=20
> See =C2=A710/1:
>=20
> "Unless redefined in the derived class, members of a base class are als=
o
> considered to be members of the derived class. ...Inherited members can=
 be
> referred to in expressions in the same manner as other members of the
> derived class, unless their names are hidden or ambiguous."
>=20

See also 9.2/2: "[...] The class-name is also inserted into the scope of
the class itself; this is known as the injected-class-name. For purposes
of access checking, the injected-class-name is treated as if it were a
public member name. [...]"

So the unqualified name of the base class is first (treated as) a member
of the base class itself by 9.2/2 and then inherited in the derived
class by 10/1.

Ganesh

---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]