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