My question is about why the following code behaves as it does. I'm not asking about the quality of the design (I know some of you will immediately hate the multiple inheritance and I'm not arguing for or against it here) I could ask a separate question that goes into what the author was trying to achieve, but lets just assume there is code that is equivalent to this:-
class IReadableData
{
public: virtual int getX() const = 0;
};
class Data : public virtual IReadableData
{
public:
virtual int getX() const { return m_x; }
void setX(int x) {m_x = x;}
private:
int m_x;
};
class ReadableData : private Data, public virtual IReadableData
{
// I'd expected to need a using here to expose Data::getX
};
This complies on visual studio 2017 with "warning C4250: 'ReadableData': inherits 'Data::Data::getX' via dominance"
Firstly I was a bit surprised not to be told that ReadableData didn't implement getX (given its implementation is private), but no warning occurs and I can create a ReadableData, but although ReadableData publicly inherits from IReadableData, the public methods of IReadableData are inaccessible
ReadableData r;
// r.getX(); error C2247: 'Data::getX' not accessible because 'ReadableData' uses 'private' to inherit from 'Data'
However the following does compile
ReadableData r;
IReadableData& r2 = r;
r2.getX();
This seems inconsistent to me either r is an IReadableData and getX should be available or it isn't and the assignment to r2 (or the definition of ReadableData) should fail. Should this happen? what in the standard leads to this?
This question:- Diamond inheritance with mixed inheritance modifers (protected / private / public)
seems connected, except that the base in that case is not abstract, and its answer citing section 11.6 would make me think that r.getX(); should have been accessible.
Edit: I made example code slightly less minimal to give a tiny bit of insight into intention, but it doesn't change the question really.