Short story:
struct A{};
struct B:private A{};
void f(void *){}
void f(A*){}
int main(){
B* b;
f(b);
}
and GCC complains
error: ‘A’ is an inaccessible base of ‘B’
Long story:
To see if a class is a subclass (or the same) of another without using boost, I do
template<typename B,typename D> struct is_base_or_same_of{
typedef char (&yes)[2] ;
static yes test(const B* b);
static char test(const void* p);
static const D* d();
static const bool value=sizeof(test(d()))==sizeof(yes);
};
and the situation is the same
How could I make the compiler “prefer” the void* version?
This has to do with the process of overload resolution and how it goes. When you pass a pointer to the derived object, the compiler will try to find the best match for the function and determines that it is the overload that takes a pointer to
A. Only then access specifiers are checked and the compiler complains thatAis not an accessible base from that context.The compiler is not allowed to go back, discard that overload and try with the rest of them.