Hello again!
In this video, we are going to look at classes and templates.
Template classes support pretty much every function that non-template classes do.
They can have friends, which are either functions or other classes.
They can have members which are static.
They can have member functions which take default arguments, and so on.
We can use template classes in inheritance hierarchies, either as base classes or derived classes,
and we can use composition.
So template classes can have members which are objects of other classes, either templated or non templated.
We can also have a member function, which is a template function.
This is called a "member template". And we can have those, even if the class is not templated.
And also the parameters for the member template do not have to be the same as the parameters for the
class.
The only restriction really is that a member template cannot be virtual.
If you remember generic lambdas, these are implemented as classes which have a member template.
We can have a generic lambda which looks like this.
So the parameters are declared as auto.
Then when we call this lambda, the compiler will deduce the type, from the arguments which are passed
to it.
This will be implemented as a class which the compiler generates. And this will have a member template.
So here is an example of a class which is not a template class, but has a member template.
When we call this lambda expression, the compiler will create an object of this functor. And then it will
call the member template with the arguments.
It will deduce the type of the arguments to the member template, from the arguments that we pass.
And it will instantiate the template with the correct argument type.
Let's look at this in the compiler.
We have our generic lambda expression here with the auto arguments.
We have the functor class that the compiler will generate. With the member template for the function call
operator.
This implements the expression body. When we call this lambda expression,
the compiler will create an object of this functor. And then it will deduce the type of the parameter
for this member template, from the arguments which we pass to it.
Then it instantiates the member template. And then it will call the function.
Okay.
Just to prove that works. We can also have a member template which has different parameter from the class.
So here is a class which has a parameter.
It has two members of that type.
There is a constructor which will initialize them. And then we have a member template, which has a different
parameter.
So this is going to call the function, and pass the members of the class as argument.
So we can create an object of this class.
So this will have members of type int, initialized from x and y.
Then we call this member function, compare.
We need to have a callable object as argument.
So we can pass a lambda expression, which will just return true if one argument is less than the other.
The compiler will deduce the type of "func" from the argument.
So that is going to be the same type as this lambda expression.
The functor that the compiler will generate. And then it will call this function.
Okay.
So it's true.
One is less than two.
Although the parameter for the member template is different from the template for the class, there
is in fact some coupling between them.
They are both subject to constraints.
The members of the class have to be a type which is comparable.
They have to support the less than operator. And the parameter of the member template has to be a callable object.
And if neither of these is true, then that will be the usual screenful of error messages, which are difficult
to decipher.
One of the main features in C++ 20 is concepts.
Concepts allow us to express constraints on template parameters. So we can specify these requirements
as part of the template definition.
So we can say that "func" has to be a callable object and the class members have to be comparable.
So this will allow us to write code which is much clearer, and makes it easier to understand what the
programmer's intentions were, when they wrote the code.
And the idea is, we will get specific compiler errors. Instead of getting screenfuls of messages,
we willl just get something saying the parameter is not callable.
Something like this.
C++20 is a very big release, and it was immediately followed by Covid and lockdown.
So implementation is rather delayed.
I think most of the concepts framework is there, but the error messages are not quite there yet.
And, in fact, it is probably going to be well into 2023 before C++20 is fully supported on all compilers.
Okay, so that is it for this video.
I will see you next time.
But until then, keep coding!