Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Private inheritance hides base class with "inaccessible within this context" error

Tags:

c++

I'm having a problem similar to that described in Private inheritance renders class inaccessible where a privately inherited base class gives an "inaccessible within this context" error when I try to declare a member of the base class inside the derived class.

Explicitly referencing X with ::X works in the above case, but what if the code is in a function such as:

void fooby()
{
    class X {};

    class Y : private X {};

    class Z : public Y
    {
    public:
        X x; // Compiler "inaccessible within this context" error
    };
};

How do you reference X in this case?

If fooby were a struct/class, then ::fooby::X would work, but I'm not sure how to do it in the case above.

like image 233
stephen_liu Avatar asked Aug 26 '11 17:08

stephen_liu


2 Answers

The problem that you are facing is that there is an injected identifier X in Y (and all derived types) that refers to X, which is not accessible below Y.

In the common case of user-defined types that are declared at namespace level, you could use the namespace to qualify the type and gain access:

class X {};
class Y : X {};
class Z : Y {
   ::X x;            // Or Namespace::X
};

Because you are defining your types inside a function that is not a valid option.

Alternatively, you can get around the problem with other workarounds. As hamstergene proposed, you can create an alternative identifier to refer to X:

typedef class X {} another_name;
class Y : X {};
class Z : Y {
   another_name x;
};

Or you can add a typedef inside Y to provide the type to derived types:

class X {};
class Y : X {
public:
   typedef X X;
};
class Z : Y {
   X x;
};

This last option works, because it will add an X identifier inside Y that is public and refers to the type, so the compiler will find the type there and use that in Z.

like image 52
David Rodríguez - dribeas Avatar answered Oct 21 '22 15:10

David Rodríguez - dribeas


I can't find a way to do that. The only option I see is to introduce typedef outside of Z:

typedef X PITA;

class Z : public Y
{
public:
    PITA x; // ok
};
like image 29
hamstergene Avatar answered Oct 21 '22 16:10

hamstergene