Home > database >  C Concepts: Checking if derived from a templated class with unknown template parameter
C Concepts: Checking if derived from a templated class with unknown template parameter

Time:04-19

Is there a way to use C concepts to require that a class is derived from a templated class, whose template parameter is again a derived class from another templated class.

Example:

template <class T>
class A{};

template <class T>
class B{};

class X{};
class Y : public A<X> {};

class Z : public B<Y> {};

How can I check in B, that T is of the form std::is_base_of<A<X>,T> for some X without specifying what X is? I don't want to add X to the template paramter list of B, because I don't want to change code at every instance where B is derived from (e.g. the last line with class Z).

CodePudding user response:

If you want to check for specialisations of A specifically, that isn't too difficult.

template <class C>
concept A_ = requires(C c) {
    // IILE, that only binds to A<...> specialisations
    // Including classes derived from them
    []<typename X>(A<X>&){}(c);
};

The lambda is basically just a shorthand for a function that is overloaded to accept A specialisations. Classes derived from such specialisations also count towards it. We invoke the lambda with an argument of the type we are checking... and the constraint is either true or false depending on whether the call is valid (the argument is accepted).

Then, just plug it in:

template <A_ T>
class B{};

Here it is working live.

  • Related