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?
Since foo
in B
is inherited from A
, &B::foo
is identical to &A::foo
, and has type void (A::*)()
. When you write
typedef void (B::*mf)();
mf func = &B::foo;
you are trying to convert from void (A::*)()
to void (B::*)()
. Since B
inherits privately fromA
you cannot do that.
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::*()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With