I'd like to enforce a CRTP template parameter to be an actual derived type. Unfortunately it seems to be impossible to express that as a constraint.
The problem is that the constrained type is undeclared in the requires clause - and a forward declaration would need the same requires clause / constraint. Another problem is that the derived class is actually incomplete at the instantion point.
It is a recursive constraint...
Is there any way to write such a constraint?
#include <type_traits>
template<typename TDerived>
requires std::is_base_of_v<Base<TDerived>, TDerived> //<-- this fails
class Base
{
};
class Sub : public Base<Sub>
{
};
/* this should be not allowed
class Sub : public Base<int>
{
};
*/
int main(int argc, char* argv[])
{
Sub s;
return 0;
}
class OtherSub : public Base<Sub> {}; // Oops it depends on Sub instead of OtherSubwhich is probably something you didn't intend to allow.Base<TDerived>is incomplete, so it can't be base of anything. Your concept definition attempts to create infinitive recursion. This concepts depends on it self.