I have this code:
class Foo
{
public:
int x = 4;
int & operator[](size_t index) { return x; }
};
class Bar : protected Foo
{
public:
using Foo::operator[];
Bar () { x++; }
};
int main(int agrc, char ** argv)
{
typedef int &(Bar::*getOp)(size_t index);
Bar b;
auto bVal = b[4];
getOp o = &Bar::operator[];
auto bVal2 = (b.*o)(7);
}
However, I cannot compile this, because
error C2247: 'Foo' not accessible because 'Bar' uses 'protected' to inherit from 'Foo'
Why is this not possible, when I have used using
and I can call operator directly? Is there any way around?
If I change inheritance to public, it is working.
Note: This is just an example of larger class. I dont want to use public inheritance, because I dont want to be able to do Foo f = Bar()
because in Bar
, I am hiding parent methods (I have not use virtual).
public inheritance makes public members of the base class public in the derived class, and the protected members of the base class remain protected in the derived class. protected inheritance makes the public and protected members of the base class protected in the derived class.
If the derived class inherits the base class in public mode, protected members of base class are protected members of derived class. public data members of base class are public members of derived class.
1) Public Inheritance: Protected members of Base class remain protected in Derived class. c. Public members of Base class remain public in Derived class. So, other classes can use public members of Base class through Derived class object.
Private Inheritance − When deriving from a private base class, public and protected members of the base class become private members of the derived class.
Why is this not possible, when I have used using and I can call operator directly?
The using declaration gives you access to the name operator[]
. But it doesn't alter the member's type. It stays
int &(Foo::*)(size_t)
. Note the Foo
.
So converting to the declared type of o
requires a conversion down the inheritance tree. This conversion must check that the target class is indeed derived from the base, but that is an inaccessible base.
One way to work around it is to give Bar
a member function that returns that pointer. Inside Bar
's scope the base will be accessible to the conversion. Also, this sort of conversion requires a static_cast
.
This conversion is not allowed once the base class Foo
is inaccessible.
Instead of using using Foo::operator[]
, maybe this can solve your problem:
int& operator[](size_t index) { // now a Bar::operator[], not Foo:: anymore
return Foo::operator[](index);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With