Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"no unique final overrider" error

212 views
Skip to first unread message

Matt Kersen

unread,
May 23, 2003, 3:42:08 PM5/23/03
to
Any idea why the code for the following inheritance hierarchy will
compile and run (using gcc 3.2):

A::func()
/ \
/ \
/ \
B::func() C
\ /
\ /
\ /
D

#include <iostream>
using namespace std;

class A
{
public:
virtual void func() { cout << "A::f()" << endl; }
};

class B : public virtual A
{
public:
virtual void func() { cout << "B::f()" << endl; }
};

class C : public virtual A
{ };

class D : public virtual B, public virtual C
{ };

int main()
{
D d;
d.func();
return 0;
}


but the code for the following inheritance hierarchy gives the
following error message:

A::func()
/ \
/ \
/ \
B::func() C::func()
| |
| |
| |
D::func() E
\ /
\ /
\ /
F

test2.cpp:32: no unique final overrider for `virtual void A::func()'
in `F'
test2.cpp: In function `int main()':
test2.cpp:37: request for member `func' is ambiguous
test2.cpp:19: candidates are: virtual void C::func()
test2.cpp:25: virtual void D::func()


#include <iostream>
using namespace std;

class A
{
public:
virtual void func() { cout << "A::func()" << endl; }
};

class B : public virtual A
{
public:
virtual void func() { cout << "B::func()" << endl; }
};

class C : public virtual A
{
public:
virtual void func() { cout << "C::func()" << endl; }
};

class D : public virtual B
{
public:
virtual void func() { cout << "D::func()" << endl; }
};

class E : public virtual C
{ };

class F : public virtual D, public virtual E
{ };

int main()
{
F f;
f.func();
return 0;
}

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]

LLeweLLyn

unread,
May 24, 2003, 7:24:03 AM5/24/03
to
matthew...@baesystems.com (Matt Kersen) writes:

> Any idea why the code for the following inheritance hierarchy will
> compile and run (using gcc 3.2):
>
> A::func()
> / \
> / \
> / \
> B::func() C
> \ /
> \ /
> \ /
> D

10.2/6:
When virtual base classes are used, a hidden declaration can be
reached along a path through the sub-object lattice that does not
pass through the hiding declaration. This is not an ambiguity. The
identical use with non-virtual base classes is an ambiguity; in
that case there is no unique instance of the name that hides all
the others.

An example like yours, but more complex, follows.

[code snipped]


> but the code for the following inheritance hierarchy gives the
> following error message:
>
> A::func()
> / \
> / \
> / \
> B::func() C::func()
> | |
> | |
> | |
> D::func() E
> \ /
> \ /
> \ /
> F

[code snipped]

Here, D::func() hides B::func(), but does not hide C::func() - so
there is no unique inheritance of the name that hides all the
others.

Shane Beasley

unread,
May 25, 2003, 9:06:16 AM5/25/03
to
matthew...@baesystems.com (Matt Kersen) wrote in message
news:<b498fd45.03052...@posting.google.com>...

> Any idea why the code for the following inheritance hierarchy will
> compile and run (using gcc 3.2):
>
> A::func()
> / \
> / \
> / \
> B::func() C
> \ /
> \ /
> \ /
> D

Only one branch of the diagram overrides A::func(); there's only one
valid override as of class D.

> but the code for the following inheritance hierarchy gives the
> following error message:
>
> A::func()
> / \
> / \
> / \
> B::func() C::func()
> | |
> | |
> | |
> D::func() E
> \ /
> \ /
> \ /
> F
>
> test2.cpp:32: no unique final overrider for `virtual void A::func()'
> in `F'
> test2.cpp: In function `int main()':
> test2.cpp:37: request for member `func' is ambiguous
> test2.cpp:19: candidates are: virtual void C::func()
> test2.cpp:25: virtual void D::func()

Look at the error, then look at the diagram. Both branches offer their
own override -- the left offers D::func() and the right offers
C::func(). As g++ puts it, there is "no unique final overrider."

You don't even need this complex scenario -- you could have done the
same with the first one:

A::func()
/ \
/ \
/ \
B::func() C::func()

\ /
\ /
\ /
D

To fix, you need to provide an override in the bottom-most class of
the diagram to tell the compiler which override to call. For instance,
to select C::func() in the second diagram:

void F::func () { C::func(); }

- Shane

0 new messages