Topic: Virtual function ambiguity


Author: ank@despammed.com (Alexander Krotov)
Date: Fri, 27 Jun 2003 17:39:25 +0000 (UTC)
Raw View
Standard 10.3p2 says:
  ...Then in any well-formed class,
  for  each virtual function declared in that class or any of its direct
  or indirect base classes there is a unique final overrider that  over-
  rides  that  function and every other overrider of that function.  The
  rules for member lookup (_class.member.lookup_) 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.

Later, in paragraph 9, there is an example

  [Example: here are some uses of virtual functions with  multiple  base
  classes:
          struct A {
              virtual void f();
          };
          struct B1 : A {   // note non-virtual derivation
              void f();
          };
          struct B2 : A {
              void f();
          };
          struct D : B1, B2 {  // D has two separate A sub-objects
          };

          void foo()
          {
              D   d;
              // A*  ap = &d; // would be ill-formed: ambiguous
              B1*  b1p = &d;
              A*   ap = b1p;
              D*   dp = &d;
              ap->f();  // calls D::B1::f
              dp->f();  // ill-formed: ambiguous
          }
  In  class  D  above there are two occurrences of class A and hence two
  occurrences of the virtual member function A::f.  The final  overrider
  of B1::A::f is B1::f and the final overrider of B2::A::f is B2::f.

In this example there is no final overrider for function f
in class D. In a way it might be considered as ambiguity, but since
the name of the function is ambiguous as well there is no way to call it
for class D object.

But let's modify class D like this:
struct D : B1, B2 {  // D has two separate A sub-objects
 using B1::f;
};

As paragraph 2 says using-declarations should be ignored,
for finding final overrider. In the same time call
 dp->f();
becomes unambiguous n respect of name lookup, but this call
remains questionable in respect of function to call.

Both latest gcc and edg choose one given with using declaration.
Is this correct behavior ?

Thank you in advance,
--
Alexander Krotov

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: rhairgroveREMOVE@THISbigfoot.com (Bob Hairgrove)
Date: Fri, 27 Jun 2003 20:19:52 +0000 (UTC)
Raw View
On Fri, 27 Jun 2003 17:39:25 +0000 (UTC), ank@despammed.com (Alexander
Krotov) wrote:

>[snip]

>But let's modify class D like this:
>struct D : B1, B2 {  // D has two separate A sub-objects
> using B1::f;
>};
>
>As paragraph 2 says using-declarations should be ignored,
>for finding final overrider. In the same time call
> dp->f();
>becomes unambiguous n respect of name lookup, but this call
>remains questionable in respect of function to call.
>
>Both latest gcc and edg choose one given with using declaration.
>Is this correct behavior ?

According to Stroustrup, yes, it is (see "The C++ Programming
Language", 3rd edition, p. 392-393). I can't quote the standard for
you because I don't have a copy, but I'm sure it must be in there
somewhere.


--
Bob Hairgrove
rhairgroveNoSpam@Pleasebigfoot.com

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Mon, 30 Jun 2003 22:19:12 +0000 (UTC)
Raw View
Bob Hairgrove wrote:
> On Fri, 27 Jun 2003 17:39:25 +0000 (UTC), ank@despammed.com (Alexander
> Krotov) wrote:
 >>
>>[snip]
>>
>>As paragraph 2 says using-declarations should be ignored,
>>for finding final overrider. In the same time call
>> dp->f();
>>becomes unambiguous n respect of name lookup, but this call
>>remains questionable in respect of function to call.
>>
>>Both latest gcc and edg choose one given with using declaration.
>>Is this correct behavior ?
>
> According to Stroustrup, yes, it is (see "The C++ Programming
> Language", 3rd edition, p. 392-393). I can't quote the standard for
> you because I don't have a copy, but I'm sure it must be in there
> somewhere.

I think Bob's argument is correct. As D has two distinct sub-objects
defining the virtual method f(), there are two methods "f()" so you
can't talk about *a* final overrider for f() *in D*. This interpretation
is implicitly confirmed by the remark after the example in paragraph 9
(which is essentially identical to yours) that says:

[...] In class D above there are two occurrences of class A and hence
two occurrences of the virtual member function A::f. The final overrider
of B1::A::f is B1::f and the final overrider of B2::A::f is B2::f.

If my interpretation is correct, the clause in paragraph 2 about
ignoring the using-declaration simply does not apply in this particular
case. The using-declaration is thus to be honored and effectively binds
the unqualified name f to B1::f.

Alberto Barbati

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]