开发者

Ambiguous access [duplicate]

This question already has answers here: Closed 11 years ago.

Possible Duplicate:

Why do multiple-inherited functions with same name but different signatures not get treated as overloaded functions?

I am getting an error:

ambiguous access of 'attach'
    could be the 'attach' in base 'A::A1'
    or could be the 'attach' in base 'B::B1'

This is the code:

class A
{
public:
    class A1
    {
    public:
        virtual void attach( A & a ) { }
    };
public:
};

class B
{
public:
    class B1
    {
    public:
        virtual void attach( B & b ) { }
    };
public:
};

class C : public A::A1, public B::B1
{
public:
    C(){ }
};

void main(int argc, char *argv[])
{
    A a;
    B b;
    C c;
    c.attach( a );
    c.attach( b );
}

I understand the error. The compiler is confused, it wants scope:

c.A::A1::attach( a );
c.B::B1::attach( b );

That syntax is horrible. 开发者_开发百科 I can define the attach methods in C, and now the compiler gets it, but I don't want to have to define all of these attach methods:

class C : public A::A1, public B::B1
{
public:
    C(){ }
void attach( A & a ) { A::A1::attach(a); }
void attach( B & b ) { B::B1::attach(b); }
};

Can anyone explain to me why the compiler is confused about 'attach' when it is clear (in my mind) which 'attach' should be used? Can anyone offer a solution that does not require scoping?

UPDATE: updated the scope in my second C example, e.g. A::A1::attach(a)

UPDATE: when investigating the duplicate noted below, I came across the solution:

class C : public A::A1, public B::B1
{
public:
    using A::A1::attach;
    using B::B1::attach;
public:
    C(){ }
};

In my 18 years as a c++ programmer, I've never had to use 'using' like that. I didn't even know that existed.


This feature is to avoid the Fragile Base Class problem. Consider what would happen if this worked as you expected- and then A::A1 adds an overload taking a B::B1 reference. Suddenly, all your call sites are ambiguous- even though you didn't change anything. This is even true if the overload is private.

Of course, in my opinion, this is highly pointless, since there are a million other ways you can break your derived classes and other problems. But that's the apparent rationale.


You can write this in class C:

using A::A1::attach;
using B::B1::attach;

Instead of

void attach( A & a ) { A::A1::attach(a); }
void attach( B & b ) { B::B1::attach(b); }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜