WEBVTT

00:00.180 --> 00:00.750
Hello again!

00:01.050 --> 00:04.080
In this video, we are going to look at classes and templates.

00:06.250 --> 00:11.200
Template classes support pretty much every function that non-template classes do.

00:11.770 --> 00:14.890
They can have friends, which are either functions or other classes.

00:15.520 --> 00:17.260
They can have members which are static.

00:17.830 --> 00:20.770
They can have member functions which take default arguments, and so on.

00:21.910 --> 00:28.060
We can use template classes in inheritance hierarchies, either as base classes or derived classes,

00:28.690 --> 00:29.950
and we can use composition.

00:30.400 --> 00:36.700
So template classes can have members which are objects of other classes, either templated or non templated.

00:39.440 --> 00:42.410
We can also have a member function, which is a template function.

00:42.770 --> 00:49.190
This is called a "member template". And we can have those, even if the class is not templated.

00:50.120 --> 00:55.580
And also the parameters for the member template do not have to be the same as the parameters for the

00:55.580 --> 00:56.000
class.

00:56.780 --> 01:00.860
The only restriction really is that a member template cannot be virtual.

01:02.980 --> 01:08.880
If you remember generic lambdas, these are implemented as classes which have a member template.

01:09.940 --> 01:12.800
We can have a generic lambda which looks like this.

01:12.820 --> 01:15.560
So the parameters are declared as auto.

01:17.350 --> 01:22.810
Then when we call this lambda, the compiler will deduce the type, from the arguments which are passed

01:22.810 --> 01:23.170
to it.

01:25.910 --> 01:32.090
This will be implemented as a class which the compiler generates. And this will have a member template.

01:32.420 --> 01:36.860
So here is an example of a class which is not a template class, but has a member template.

01:38.720 --> 01:44.780
When we call this lambda expression, the compiler will create an object of this functor. And then it will

01:44.780 --> 01:47.840
call the member template with the arguments.

01:48.200 --> 01:54.290
It will deduce the type of the arguments to the member template, from the arguments that we pass.

01:54.650 --> 01:59.120
And it will instantiate the template with the correct argument type.

02:01.150 --> 02:02.800
Let's look at this in the compiler.

02:03.130 --> 02:07.420
We have our generic lambda expression here with the auto arguments.

02:08.200 --> 02:14.380
We have the functor class that the compiler will generate. With the member template for the function call

02:14.530 --> 02:15.130
operator.

02:15.580 --> 02:21.760
This implements the expression body. When we call this lambda expression,

02:22.270 --> 02:27.880
the compiler will create an object of this functor. And then it will deduce the type of the parameter

02:27.880 --> 02:31.000
for this member template, from the arguments which we pass to it.

02:31.570 --> 02:36.400
Then it instantiates the member template. And then it will call the function.

02:38.710 --> 02:39.100
Okay.

02:39.100 --> 02:44.770
Just to prove that works. We can also have a member template which has different parameter from the class.

02:45.310 --> 02:48.010
So here is a class which has a parameter.

02:48.310 --> 02:50.380
It has two members of that type.

02:51.430 --> 02:58.030
There is a constructor which will initialize them. And then we have a member template, which has a different

02:58.030 --> 02:58.540
parameter.

02:58.930 --> 03:04.690
So this is going to call the function, and pass the members of the class as argument.

03:06.670 --> 03:09.070
So we can create an object of this class.

03:09.490 --> 03:14.080
So this will have members of type int, initialized from x and y.

03:15.760 --> 03:18.820
Then we call this member function, compare.

03:19.150 --> 03:21.490
We need to have a callable object as argument.

03:22.570 --> 03:29.440
So we can pass a lambda expression, which will just return true if one argument is less than the other.

03:32.780 --> 03:38.390
The compiler will deduce the type of "func" from the argument.

03:38.390 --> 03:41.060
So that is going to be the same type as this lambda expression.

03:41.120 --> 03:45.920
The functor that the compiler will generate. And then it will call this function.

03:48.090 --> 03:48.480
Okay.

03:48.480 --> 03:49.140
So it's true.

03:49.410 --> 03:51.000
One is less than two.

03:53.350 --> 03:58.750
Although the parameter for the member template is different from the template for the class, there

03:58.750 --> 04:00.220
is in fact some coupling between them.

04:01.060 --> 04:03.070
They are both subject to constraints.

04:03.610 --> 04:06.820
The members of the class have to be a type which is comparable.

04:06.880 --> 04:13.390
They have to support the less than operator. And the parameter of the member template has to be a callable object.

04:13.780 --> 04:19.540
And if neither of these is true, then that will be the usual screenful of error messages, which are difficult

04:19.720 --> 04:20.680
to decipher.

04:23.200 --> 04:26.980
One of the main features in C++ 20 is concepts.

04:27.880 --> 04:35.530
Concepts allow us to express constraints on template parameters. So we can specify these requirements

04:35.530 --> 04:37.450
as part of the template definition.

04:37.870 --> 04:44.500
So we can say that "func" has to be a callable object and the class members have to be comparable.

04:45.370 --> 04:49.870
So this will allow us to write code which is much clearer, and makes it easier to understand what the

04:49.870 --> 04:51.970
programmer's intentions were, when they wrote the code.

04:52.870 --> 04:59.710
And the idea is, we will get specific compiler errors. Instead of getting screenfuls of messages,

04:59.710 --> 05:03.350
we willl just get something saying the parameter is not callable.

05:03.430 --> 05:04.120
Something like this.

05:05.020 --> 05:09.820
C++20 is a very big release, and it was immediately followed by Covid and lockdown.

05:09.820 --> 05:12.130
So implementation is rather delayed.

05:13.120 --> 05:19.630
I think most of the concepts framework is there, but the error messages are not quite there yet.

05:20.440 --> 05:26.890
And, in fact, it is probably going to be well into 2023 before C++20 is fully supported on all compilers.

05:27.970 --> 05:29.320
Okay, so that is it for this video.

05:29.560 --> 05:30.400
I will see you next time.

05:30.400 --> 05:32.800
But until then, keep coding!
