Why is the call to f
not resolving to the first function overload? I get the error:
source.cpp: In function 'int main()':
source.cpp:12:31: error: 'A' is an inaccessible base of 'B'
class A {}; class B : A {};
void f(const A &) { std::cout << "const A &"; }
template <typename T> void f(T) { std::cout << "Generic"; }
int main() {
B b;
f(dynamic_cast<const A &>(b));
}
Note that if I take out the dynamic_cast
the code will work yet the second f
is called (it prints "Generic"). But what I'm trying to do is to get the first call. I figured a dynamic_cast
would work, but for some reason it causes problems. What am I doing wrong here?
The default class inheritance is private (
class B : A {};
defaults toclass B : private A {};
).So you can't handle
b
through typeA
.EDIT: Like Rob said :), the way to fix it is by using public inheritance:
EDIT:
The relationship between a publicly derived class and its base class is "is a", meaning that it is a specialization of a more generic type, and as such, it implements the behavior of that generic class and possibly more.
The relationship between a privately derived class and its base class is "implemented in terms of". It prevents objects from being considered extensions of the base class. A good example of its use is
boost::noncopyable
that prevents objects of a privately derived class from being copied. http://www.boost.org/doc/libs/1_52_0/libs/utility/utility.htm#Class_noncopyableIn the hypothetical case that the requirements include private inheritance and at some point a function is created that wants to reference the object as its base, a public method returning a casted to base class pointer
this
will do it much like a traditionalget()
accesses a private data member maintaining the original purpose.And then accessed like this:
There's nothing special about
dynamic_cast
when it comes to upcasts.dynamic_cast
is equivalent tostatic_cast
in such cases. It is performed at compile-time if the base exists, is unambiguous and is accessible. It fails to compile otherwise.This is exactly what happens in your case. The base is inaccessible (as the compiler told you already) so the cast fails to compile.
Without the cast the first function is excluded from the overload resolution candidate list (since the base is inaccessible), and the second one wins.
In fact, you don't really need any cast to perform legal upcasts in overwhelming majority of cases. As for illegal upcasts, no C++ cast will help you with that (the only cast that can "break through" private inheritance is C-style cast.)
A
is a private base ofB
, so there are very few places where an object of typeB
can be treated as anA&
. If you change the inheritance to public the cast will work, and select the non-template version off
. Butdynamic_cast
is overkill; every object of typeB
is an object of typeA
, so you can usestatic_cast
to disambiguate the call.It will fail because of the private inheritance, as mentioned, and because
b
is passed as an object.dynamic_cast
will only work for pointers and references.See: http://www.cplusplus.com/doc/tutorial/typecasting/