https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58040
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|ASSIGNED |RESOLVED Resolution|--- |INVALID --- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Matt Whitlock from comment #8) > As you can see, it is possible to call all four member functions directly > using their qualified names, Yes, because the /name/ of the function is accessible in Derived, because the using-declarations delcare them as publicly accessible members of Derived. > but it is not possible to assign the addresses > of the members from the protected base into variables whose type is pointer > to member function of the derived class, Because that's not the type of the function, and [conv.mem] p2 says you can't convert them from void (ProtectedBase::*)() to void (Derived::*)() because that base class is not accessible. [conv.mem] p2 says: A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a complete class derived (11.7) from B. If B is an inaccessible (11.8), ambiguous (6.5.2), or virtual (11.7.2) base class of D, or a base class of a virtual base class of D, a program that necessitates this conversion is ill-formed. > nor is it possible to call the > members of the protected base indirectly through pointers to member function > of the derived class. You are not calling them by name here, so the using-declaration isn't relevant. You are trying to invoke a member of the protect base through the derived type, which requires converting &d to a ProtectedBase*, which is not an allowed conversion. Not a bug, this is how C++ works.