C++20: Useful concepts: Requiring type T to be derived from a base class

How can I create a concept that requires my parameterized types to inherit from a base class?

I am creating a heavily object-oriented class hierarchy and I want the functions related to that class hierarchy to accept only instances of classes derived from the base class of that hierarchy.

So, for example, I have this base class:

class Object
{
public:
    virtual ~Object() = default;

    virtual std::string to_string() const = 0;
};

I create derived classes from such class, for example: class Int.

class Int : public Object
{
    int n;
public:
    Int(int n) : n{n}  {}

    std::string to_string() const override
    {
        return std::to_string(n);
    }
};

And now I want to create a function template “print” that invokes the method “to_string()” of the given parameter and prints it out.

Because of my design, I want my function template to accept only instances of classes derived from my class Object.

In this case, I can create a C++20 concept using the type trait std::is_base_of<Base, Derived>, like this:

#include <type_traits>

template <typename T>
concept ConceptObject = std::is_base_of<Object, T>::value;

In the lines above, I am creating a new C++20 concept called “ConceptObject” that will require my type T fulfill the requirement of T being a derived class from Object.

So, finally, my function template “print” can be expressed in this way:

template <ConceptObject T>
void print(const T& s)
{
    std::cout << s.to_string() << "\n";
}

And it will only compile if the parameter s is an instance of a class derived from Object:

int main()
{
    print(Int{5});
}

Pretty nice!

If you want to read more about C++ concepts, I have this post introducing them: C++20: Concepts, an introduction