Topic: using declarations


Author: "Nathanael Rensen" <---nathanael@atri.curtin.edu.au>
Date: 1998/01/21
Raw View
I have been trying to understand 'using declarations' and have come across a
couple of issues in the Dec '96 Draft Working Paper that cause me some
confusion.

The primary issue is: what is the motivation for insisting that using
declarations be ignored for virtual member function name lookup.  From
(10.3-2):

"The rules for member lookup (10.2) are used to determine the final
overrider for a virtual function in the scope of a derived class but
ignoring names introduced by using-declarations."

Nevertheless, given this rule I have trouble understanding the example in
(7.3.3-13). A simplified version is shown below:

struct B {
virtual void f(int);
virtual void f(char);
};

struct D : B {
using B::f;
void f(int); // ok: D::f(int) overrides B::f(int);
};

void k(D* p)
{
p->f(1); // calls D::f(int)
p->f( a ); // calls B::f(char)
}

I don't understand why p->f('a') should call B::f(char).  From (10.2-2):

"The following steps define the result of name lookup in a class scope, C.
First, every declaration for the name in the class and in each of its base
class sub-objects is considered. A member name f in one sub-object B hides a
member name f in a sub-object A if A  is a base class sub-object of B. Any
declarations that are so hidden are eliminated from consideration."

If the 'using B::f' is to be ignored for member-name lookup, then why
doesn't D::f(int) hide B::f.

On a different note, (7.3.3-1) says:

"A name specified in a using-declaration in a class or namespace scope shall
not already be a member of that scope."

How is this circumvented for the example in (7.3.3-11)? (simplified version
below):

namespace B {
void f(int);
void f(double);
}

void func()
{
void f(char);
using B::f;   // f is already a member of this scope from the previous line
}

Nathanael
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Brad Daniels" <brad.daniels@missioncritical.com>
Date: 1998/01/23
Raw View
Nathanael Rensen <---nathanael@atri.curtin.edu.au> wrote in message
<6a4du8$4gc$1@info.curtin.edu.au>...
...
>The primary issue is: what is the motivation for insisting that using
>declarations be ignored for virtual member function name lookup.  From
>(10.3-2):

I believe there's a case involving multiple inheritance that could otherwise
result in odd behavior, but I can't think of it off the top of my head, and
I may be suffering from delusions in any case.

>"The rules for member lookup (10.2) are used to determine the final
>overrider for a virtual function in the scope of a derived class but
>ignoring names introduced by using-declarations."

Not that this rule applies only to determining which virtual function to
override.

...
>struct B {
>virtual void f(int);
>virtual void f(char);
>};
>
>struct D : B {
>using B::f;
>void f(int); // ok: D::f(int) overrides B::f(int);
>};
>
>void k(D* p)
>{
>p->f(1); // calls D::f(int)
>p->f(a); // calls B::f(char)
>}
...
>If the 'using B::f' is to be ignored for member-name lookup, then why
>doesn't D::f(int) hide B::f.

Because using declarations aren't ignored for member name look up.  They're
only ignored for determining which function to override.

>On a different note, (7.3.3-1) says:
>
>"A name specified in a using-declaration in a class or namespace scope
shall
>not already be a member of that scope."
>
>How is this circumvented for the example in (7.3.3-11)? (simplified version
>below):
>
>namespace B {
>void f(int);
>void f(double);
>}
>
>void func()
>{
>void f(char);
>using B::f;   // f is already a member of this scope from the previous line
>}

Well, in that example, you're at function scope, not class or namespace
scope...  However, similar things would work at class scope, at the very
least.  I can't find an exact reference, but I believe that function names
are treated differently from other names.  For example:

struct x {
   enum { f };
};

struct c : public x {
   enum { f };
   using x::f;
};

Is not legal.

- Brad
---
[ 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                             ]