I am surprised that in the following example declaring Middle's base class private makes that name unavailable as a type in a subsequent derivation.
class Base {
public:
  Base(Base const& b) : i(b.i) {}
  int i;
};
class Middle : private Base {            //<<<<<<<<<<<
public:
  Middle(Base const* p) : Base(*p) {}
};
class Upper : public Middle {
public:
  Upper(Base const* p) : Middle(p) {}    //<<<<<<<<<<<
};
Compiling thusly with g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516...
g++ -std=c++11 privateBase.cpp
I get the following diagnostics:
privateBase.cpp:15:9: error: ‘class Base Base::Base’ is inaccessible within this context
   Upper(Base const* p) : Middle(p) {}
         ^~~~
privateBase.cpp:1:12: note: declared here
 class Base {
            ^
Clearly at the point that Base was used as Middle's base class its name was available as a type. I can understand that when Base is used to denote base class storage that should be private. But having a declaration of a private base class render a type name inaccessible seems, at the very least, unexpected.
 
     
    