c++inheritanceusing-declaration

hiding a parent class but not the grandparent in C++


Is it possible to skip a generation with regards to class visibility?

The following works for gcc compilers but not clang nor intel. They fail with error: cannot cast 'C' to its protected base class 'A'

struct A {};
struct B: public A {int stuff() {} };
struct C: protected B { using B::A; }; // want to hide stuff from `B`, but keep the identity as an `A`

void call(A &) {}

int main()
{
    C c;
    call(c);
}

Is GCC overly accommodating in this case or is it correct?

The A and B in this example represent two classes that cannot be changed. For a solution to be usable, it has to be done in the C class.

For those who want an unnecessary level of detail ...

C is a class that provides new functionality by hiding and extending all the methods in B (all non-virtual). Those B methods are designed to be chained together, with each one returning a B&. There is a lot of existing trusted code that uses this chaining. The idea is to minimally change such code from declaring the chained objects from B to C to get the improved functionality.

workable solution (distasteful) I should come clean and admit that I can (and currently do) have it working by simply omitting the protected inheritance. The C methods hide all the B methods. But it seems brittle. If a new method gets added to the library B class and new code uses it, there would be runtime errors. I'd like to make the B methods inaccessible to turn those into compilation errors.


Solution

  • Is GCC overly accommodating in this case or is it correct?

    This is a confirmed gcc bug which had a reduced example for the same:

    class A {};
    
    class B : public A {};
    
    class C : B
    {
    public:
      using B::A;
    };
    
    int main()
    {
      A *p = new C;
    }