The compilation of the next example :
class A
{
public:
void foo()
{
}
};
class B : private A
{
public:
using A::foo;
};
int main()
{
typedef void (B::*mf)();
mf func = &B::foo;
B b;
(b.*func)();
}
fails with next errors :
main.cpp||In function ‘int main()’:
main.cpp|18|error: ‘A’ is an inaccessible base of ‘B’
main.cpp|18|error: in pointer to member function conversion
I understand that the A is not accessible base of B, but I am using the using
keyword. Shouldn't it allow the access to the function foo?
What are relevant paragraphs in the standard that prevents the above to be compiled?
Access to members of A
is governed by chapter 11 "Member Access Control", but pointer-to-member conversions are covered by 4.11. In particular, 4.11/2 states that you can't convert a T A::*
to an T B::*
when you can't convert an B*
to a A*
.
Here's a slight variation of the question:
class A
{
public:
void foo()
{
}
};
class B : private A
{
public:
using A::foo;
};
int main()
{
typedef void (A::*amf)();
typedef void (B::*bmf)();
amf func = &A::foo;
bmf f2 = static_cast<bmf>(func);
}
We're still talking about the same function. It's not the name lookup of B::foo
that fails (using
takes care of that), it's the fact that the type of B::foo
is void A::*()
which cannot be converted to void B::*()
.