The following code fails to compile on g++ 4.6.1:
template<class Base>
struct GetBase {
Base * getBase() {
return static_cast<Base *>(this);
}
};
template<class Derived>
struct Parent : private GetBase<Derived> {
using GetBase<Derived>::getBase;
int y() {
return getBase()->x();
}
};
struct Child : public Parent<Child> {
int x() {
return 5;
}
int z() {
return y();
}
};
with the error
In member function ‘Base* GetBase<Base>::getBase() [with Base = Child]’:
instantiated from ‘int Parent<Derived>::y() [with Derived = Child]’
instantiated from here
error: ‘GetBase<Child>’ is an inaccessible base of ‘Child’
Changing the static_cast to a reinterpret_cast will get the code to compile and it will work in this case, but I’m wondering if this is an acceptable solution in all cases? i.e., is it ever the case that a pointer to a base class is not the same as this? I’m assuming with multiple inheritance this may happen if the parents have data members? If GetBase is the first superclass, are the this pointers guaranteed to be equal?
A good question; it caused me to learn something new about
static_cast.I think the following code achieves what you want : provides a base class for CRTP with a member function that casts
thisto the Derived type, yet only makes it accessible to the direct descendants of this base class. It compiles with GCC 4.3.4 (tested at ideone) and Clang (tested at llvm.org). Sorry, I couldn’t resist to changing the names that I find confusing.This variant works because the inheritance is public, which enables the standard conversion of a pointer-to-derived-class to a pointer-to-base-class, and so also the inverse conversion (from base to derived) with
static_cast, which CRTP needs. Private inheritance in your code prohibited this. So I made inheritance public, changed the method to be protected, and inParentfurther restricted access by putting theusingdeclaration into private section.