Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using std::is_base_of in static_assert fails due to incomplete type

What I am trying to do is have some classes inherit form an extention class. The thing is the extention class has to know which class it is extending.

This can simply be achieved like this:

template<typename Self>
class Extention
{
    public:
        void check() const
        {
            std::cout << "Extention is valid: "
                      << std::boolalpha
                      << std::is_base_of<Extention, Self>::value
                    << std::endl;
        }
};
class Foo : public Extention<Foo> {};
class Bar : public Extention<void> {};

The Foo and Bar class show good, and bad usage of the extention.

Foo().check(); → Extention is valid: true
Bar().check(); → Extention is valid: false

I would like to check the validity of the template during compilation, which brought me to write

template<typename Self>
class Extention
{
    static_assert(std::is_base_of<Extention, Self>::value);
};

However, gcc tels me this static_assert is wrong as class Foo has incomplete type.

What am I doing wrong ?

Edit: I'm using -std=c++17, error is not the lack of error message in the static_assert

like image 247
Amxx Avatar asked Oct 17 '22 07:10

Amxx


1 Answers

What am I doing wrong ?

Because of [meta.rel], std::is_base_of requires that the derived type is a complete type:

If Base and Derived are non-union class types and are not possibly cv-qualified versions of the same type, Derived shall be a complete type.

On the other side, [class.mem/6] states that:

A class is considered a completely-defined object type (or complete type) at the closing } of the class-specifier. [...]

That isn't your case. When you instantiate Extension<Foo>, Foo itself is far from being completely-defined.

In other terms, you cannot use that static_assert at the class scope. Put it in the destructor's body (my preferred solution actually, even though it has a few drawbacks) or any other (special) member method's body if you prefer.

like image 63
skypjack Avatar answered Oct 20 '22 23:10

skypjack