0
votes

If I have a template base class that takes the type of the derived class, is safe to cast the this pointer of this base class to the type of the derived class?

Consider this code, where the base class A casts the this pointer to a template parameter (Derived). It also checks if the provided type is actually derived from this class. It obviously works (here), but is it well defined?

#include <iostream>

class D;

template<typename Derived, typename T>
class A
{
public:
    Derived *thisToDerived() {
        static_assert(std::is_base_of< A<Derived, T>, Derived>::value, "not");
        return static_cast<Derived*>(this);
    }
private:
    T m;
};


class D : public A<D, int>
{
private:
    double d;
    float f;
};


int main() {
    D d;
    std::cout<<"this:    "<<&d<<"\nderived: "<<d.thisToDerived();
}
1
Also related, almost answers this: stackoverflow.com/q/4173254/1896169Justin
To put it simply, yes this is safeJustin
is_base_of< A<Derived, T>, D> seems to be wrong. If you restrict potential derived classes to D alone, you don't need to define any templates. Perhaps you meant is_base_of< A<Derived, T>, Derived>.n. 1.8e9-where's-my-share m.
yes, this was what i mean.dani

1 Answers

2
votes

If I have a template base class that takes the type of the derived class, is safe to cast the this pointer of this base class to the type of the derived class?
...
It obviously works (here), but is it well defined?

Yes, it's safe and is well defined. It's actually a well known and commonly used pattern (see CRTP) and aka Static Polymorphism.

Examples of usage:


Derived *thisToDerived() {
    // Your static_assert is superfluos
    // static_assert(std::is_base_of< A<Derived, T>, Derived>::value, "not");
    return static_cast<Derived*>(this);
        // ^^^^^^^^^^^^^^^^^^^^^
        // Already guarantees that Derived is inherited from A
}