11

In this code assigning to b1 works, but it won't allow assigning to b2 (with or without the static cast). I was actually trying to solve the opposite problem, public inheritance but not implicitly converting to the base. However the cast operator never seems to be used. Why is this?

struct B {};    

struct D1 : private B {
    operator B&() {return *this;}
    B& getB() {return *this;}
};

struct D2 : public B {
    explicit operator B&() {return *this;}
};

struct D3 : public B {
    operator B&() = delete;
};

void funB(B& b){}

int main () {
  D1 d1;
  funB(d1.getB()); // works
  // funB(d1); // fails to compile with 'inaccessible base class
  D2 d2;
  funB(d2); // works
  D3 d3;
  funB(d3); // works 
  return 0;
}
Bas
  • 474
  • 1
  • 4
  • 12
  • I can't replicate the compilation error you describe. – Peter Mar 21 '16 at 13:20
  • @Peter: Replicated [here](http://ideone.com/hKSEAo) – R_Kapp Mar 21 '16 at 13:23
  • @Barabas: I'll wait for someone with an appropriate quote from the standard to provide the answer, but think of public inheritance as "is-a" and private inheritance as "has-a". I.e., `D2` and `D3` are special instances of `B`, whereas `D1` is it's own thing that happens to *have* a `B`. – R_Kapp Mar 21 '16 at 13:24
  • What is the point of "private" inheritance here? – lulyon Mar 21 '16 at 13:30
  • 4
    There doesn't have to be a point. This could be a MCVE of real world code or it could just be code written to expand understanding of the C++ standard. – Simple Mar 21 '16 at 13:43
  • @lulyon I was just trying around. I mainly want to inherit without implicitly converting to the base class, but explicit conversion would be ok. I guess it's impossible. – Bas Mar 21 '16 at 14:37

1 Answers1

11

From [class.conv.fct]:

A conversion function is never used to convert a (possibly cv-qualified) object to the (possibly cv-qualified) same object type (or a reference to it), to a (possibly cv-qualified) base class of that type (or a reference to it), or to (possibly cv-qualified) void.

So in your first example:

struct D1 : private B {
    operator B&() {return *this;}
    B& getB() {return *this;}
};

operator B& will never be used because it converts to a base class. It doesn't matter that it's a private base class.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • So if I understand it correctly it's impossible to inherit while having explicit conversion, but not implicit, right? – Bas Mar 21 '16 at 14:38
  • @Barabas Not sure what you are asking. – Barry Mar 21 '16 at 14:43
  • Either you inherit publicly and your class will implicitly convert to it's base, or you inherit privately (or protected) and it won't convert at all, not even with a static_cast/constructor. There is no way around it, right? – Bas Mar 21 '16 at 19:21