c++templatesrequires-clause

How to do a condition on a template for a class to be derived from a templated Base class, where the template parameter is given by the derived class?


I have a base class taking a template size_t parameter and 2 derived class giving the template argument to the base class.

template<size_t N>
class BaseClass
{
  size_t value = N;
};

class Derived1 : public BaseClass<1>
{};

class Derived2 : public BaseClass<2>
{};

Now I want to create a templated function on any class that derives from the Baseclass. so I wanted to create a template on a generic class T and use a requirement with std::is_base_of_v(...) to ensure that T isa BaseClass.

Problem when giving the parent class I also need to precise the size_t templated parameter which is stored in T.

I end up with the following:

template<class T>
  requires std::is_base_of_v<BaseClass<T.value>, T>
void
function(T arg) {};

Obviously this does not compile because T is a generic class and does not hold the attribute value, the only way to get around this I found is to add another size_t template parameter to the function and use this in the BaseCLass:

template<class T, size_t N>
  requires std::is_base_of_v<BaseClass<N>, T>
void
function(T arg) {};

And this (should) work, but I am not convinced by the solution as I end up with a redundancy of N which I have to give to the function's template manually as well as the Derived class which already holds the value. It there any way around this ?


Solution

  • Not exactly the same constraint, but you might do:

    template<class T>
    requires requires(T t) {
        []<std::size_t N>(const BaseClass<N>& ){}(t);
    }
    void function(T arg) {
       // ...
    }
    

    Demo