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
What am I doing wrong ?
Because of [meta.rel], std::is_base_of
requires that the derived type is a complete type:
If
Base
andDerived
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With