This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 116a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-19
[Accepted at the November, 2020 meeting as part of paper P1787R6 and moved to DR at the February, 2021 meeting.]
I have heard a claim that the following code is valid, but I don't see why.
struct A { int foo (); }; struct B: A { private: using A::foo; }; int main () { return B ().foo (); }
It seems to me that the using declaration in B should hide the public foo in A. Then the call to B::foo should fail because B::foo is not accessible in main.
Am I missing something?
Steve Adamczyk: This is similar to the last example in 11.8.3 [class.access.base]. In prose, the rule is that if you have access to cast to a base class and you have access to the member in the base class, you are given access in the derived class. In this case, A is a public base class of B and foo is public in A, so you can access foo through a B object. The actual permission for this is in the fourth bullet in 11.8.3 [class.access.base] paragraph 4.
The wording changes for issue 9 make this clearer, but I believe even without them this example could be discerned to be valid.
See my paper J16/96-0034, WG21/N0852 on this topic.
Steve Clamage: But a using-declaration is a declaration (9.9 [namespace.udecl]). Compare with
struct B : A { private: int foo(); };
In this case, the call would certainly be invalid, even though your argument about casting B to an A would make it OK. Your argument basically says that an access adjustment to make something less accessible has no effect. That also doesn't sound right.
Steve Adamczyk: I agree that is strange. I do think that's what 11.8.3 [class.access.base] says, but perhaps that's not what we want it to say.