Why am I getting the error "A - Inaccessible Base B" when using dynamic_cast and templates?

Why doesn't calling f allow overloading the first function? I get an error message:

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 rip out <<24>, the code will work, but the second f is called (it prints "Generic"). But I'm trying to make the first call. I decided that dynamic_cast would work, but for some reason it causes problems. What am I doing wrong here?

+4
source share
4 answers

Class inheritance is private by default ( class B : A {}; default is class B : private A {}; ).

So you cannot handle b through type A

EDIT: Like Rob said :), a way to fix this using public inheritance:

 class B : public A {}; 

EDIT:
The connection between a public derived class and its base class is "there", which means that it is a specialization of a more general type, and as such it implements the behavior of this generic class and, possibly, more.

The relationship between a private derived class and its base class is "in terms of". This does not allow objects to be considered extensions of the base class. A good example of its use is boost::noncopyable , which prevents copying of objects of a class derived from a private class. http://www.boost.org/doc/libs/1_52_0/libs/utility/utility.htm#Class_noncopyable

In the hypothetical case that the requirements include private inheritance, and at some point a function is created that wants to refer to the object as its base, the public method that returns the casted to base class this pointer will be very similar to the traditional get() call A private data item that supports the original target.

 public: A *getBase() { return static_cast<A *>(this); } 

And then follow these steps:

 f(b.getBase()); 
+7
source

A is a private base of B , so there are very few places where an object of type B can be considered as A& . If you change the inheritance for the public, the action will be completed and select the version without the template f . But dynamic_cast is redundant; each object of type B is an object of type A , so you can use static_cast to disambiguate the call.

+4
source

There is nothing special about dynamic_cast when it comes to updates. dynamic_cast equivalent to static_cast in such cases. It is performed at compile time, if the database exists, is unambiguous and available. Otherwise, it does not compile.

This is exactly what happens in your case. The database is unavailable (as the compiler has already reported), so compilation is not performed.

Without a throw, the first function is excluded from the list of candidates for overload resolution (since the base is unavailable), and the second wins.

In fact, you really do not need to apply to perform legal exams in the vast majority of cases. As for illegal upcasts, no C ++ throw will help you with this (the only tide that can “break through” through private inheritance is C-style.)

+1
source

It will fail due to 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/

0
source

All Articles