20
votes

I'm having a problem similar to that described in the following link 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: http://bytes.com/topic/c/answers/164246-private-inheritance-renders-class-inaccessible

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.

2
What are you trying to do having both a member and base class of the same type? Maybe that would help with an alternate suggestion.Mark B
@Mark B - this is just a simple contrived example to illustrate the behavior that I'm trying to understandstephen_liu

2 Answers

13
votes

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 @Eugene 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.

9
votes

Good question, 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
};