Max Gómez
Max Gómez

Reputation: 69

Static Assert Template inherits from class

How can I guarantee that T inherits from Base<T>?

So I have

#include <type_traits>

template <typename T>
class Base { 
public:
    static_assert(std::is_convertible<T*, Base<T>*>::value, "Class must inherit Base as public");
};

class DerivedWithPublic : public Base<DerivedWithPublic> { };

int main() {
    DerivedWithPublic p;
    static_assert(std::is_convertible<DerivedWithPublic*, Base<DerivedWithPublic>*>::value, "Class must inherit Base as public");
}

The static_assert in main is true. However the one inside of base is false! So the compiler fails. I want the assertions to be within the class itself? Firstly, i dont understand why one passes and the other one doesn't. Secondly, I need a solution. Thanks in advance.

Upvotes: 1

Views: 587

Answers (1)

GAVD
GAVD

Reputation: 2134

Base<DerivedWithPublic> is instantiated at the point where it appears in DerivedWithPublic's list of base, at which time DerivedWithPublic is not yet complete type since its declaration hasn't been parsed yet. You can delay assertion until it is completed. One possible solution for this problem is to put the assertion in a member function of Base that you know must be instantiated, for example the destructor.

Live example

#include <type_traits>

template <typename T>
class Base { 
public:
    ~Base() {
        static_assert(std::is_convertible<T*, Base<T>*>::value, "Class must inherit Base as public");
    }    
};

class DerivedWithPublic : public Base<DerivedWithPublic> { };

int main() {
    
}

Upvotes: 3

Related Questions