WEBVTT

00:00.120 --> 00:00.690
Hello again!

00:00.990 --> 00:04.350
In this video, we are going to look at miscellaneous template features.

00:06.460 --> 00:12.550
The assert() function, or macro, I think, is inherited from C. It is in the <cassert> header.

00:13.570 --> 00:15.660
assert() will check its argument at run-time.

00:16.000 --> 00:22.030
If the argument is zero, it will call the library abort() function, which will terminate the program

00:22.090 --> 00:22.690
immediately.

00:23.380 --> 00:28.900
Otherwise, if the arguments is not zero, then the program will continue executing, as normal.

00:29.830 --> 00:33.000
So if 'x' is equal to 42, then nothing will happen.

00:33.010 --> 00:34.090
The program will continue.

00:34.810 --> 00:39.070
If 'x' is not equal to 42, then the program will terminate immediately.

00:40.090 --> 00:42.340
And this is useful for checking invariants.

00:42.880 --> 00:44.560
So these are things that must be true.

00:45.220 --> 00:49.900
For example, if you are going to pass 'x' to a function, and it is very important that the function argument

00:49.900 --> 00:58.240
has the value 42, then this is one way that you can enforce that. There is some runtime overhead to

00:58.240 --> 00:59.170
doing these checks.

01:00.010 --> 01:06.620
And also this is really something that you do not want, in code that is being used by customers. Just

01:06.620 --> 01:08.260
existing with no explanation.

01:08.950 --> 01:10.930
So it is possible to turn this off.

01:11.440 --> 01:17.800
If you define the symbol 'NDEBUG' in the pre-processor, then the assert macro does nothing at all.

01:20.160 --> 01:26.070
In C++11, we have a compile-time version of assert(), called static underscore assert.

01:27.030 --> 01:29.700
This takes a bool argument, and a string.

01:30.540 --> 01:32.880
These have to be available at compile time.

01:33.330 --> 01:40.500
So the bool has to be a constant expression, and the string has to be a string literal. Not a C++ library

01:40.500 --> 01:41.010
string.

01:42.180 --> 01:44.730
The compiler will evaluate this bool.

01:45.450 --> 01:50.850
If the bool evaluates as false, then the compiler will immediately stop processing the source code.

01:51.360 --> 01:55.320
And it will produce an error, which includes the string as part of the error message.

01:57.400 --> 02:03.310
If the bool evaluates to true, then the compiler will carry on, and compile the rest of the source code.

02:04.720 --> 02:09.010
So if the size of int is equal to 8, then nothing will happen.

02:09.850 --> 02:15.760
If size of int is not equal to 8, then the compiler will stop. And the error message will include

02:15.760 --> 02:16.210
the words,

02:16.510 --> 02:19.210
"This program requires a 64-bit compiler"

02:21.200 --> 02:23.730
The main use for this is in template

02:23.780 --> 02:26.390
metaprogramming, again for checking invariants.

02:27.290 --> 02:32.810
If you have a template function, and your code assumes that one of the arguments can be copied, you

02:32.810 --> 02:36.650
can check this, by using static_assert() with a type trait.

02:40.440 --> 02:44.370
So let's quickly try that out. And we get a compiler error.

02:44.730 --> 02:47.370
"This requires a 64-bit compiler"

02:48.180 --> 02:54.660
And in fact, I am compiling in 32-bit mode. And in 32-bit mode, the size of int is 4.

02:55.290 --> 02:59.940
So this boolean is false, and we get this error message when the compiler stops.

03:02.140 --> 03:07.390
We can have template classes which have a default type parameter, or parameters, in the plural.

03:08.350 --> 03:09.730
We write them like this.

03:10.270 --> 03:14.410
So by default, the template parameter is type int.

03:16.710 --> 03:22.950
And then we can just instantiate this, like a normal template class. So we can put long double as the

03:22.950 --> 03:26.460
type parameter, and then this member will be a long double.

03:27.540 --> 03:33.390
If we leave the angle brackets empty, then we gets the default. And this member will be an int.

03:36.530 --> 03:43.190
So here is that class. We have a constructor, to initialize the member. And a function, which will print

03:43.190 --> 03:46.150
out the member. In the main function,

03:46.160 --> 03:49.630
we instantiate this with long double as the type parameter.

03:50.030 --> 03:51.290
So this will be long double.

03:52.370 --> 03:59.570
And then we instantiate again, using the default type parameter of int.

04:01.200 --> 04:02.600
And then we print out the member.

04:07.400 --> 04:13.790
So with the long double, we get 1.99999, and with the default we get 1, because the int has

04:13.790 --> 04:17.090
been truncated. And you might get a compiler warning about that.

04:19.860 --> 04:25.350
In C++11, it is now possible to have a template function with default parameters.

04:26.070 --> 04:27.480
It is the same syntax again.

04:27.810 --> 04:32.850
So by default, "t1" and "t2" will be const reference to int.

04:34.410 --> 04:39.030
And then we just call the template function as normal, and the compiler will deduce the types.

04:40.650 --> 04:45.060
So here we have this function, which will just print out the sum of its arguments.

04:46.140 --> 04:50.490
Then we can have long double and int variables, which we pass to the function.

04:51.390 --> 04:54.510
And then when we call, it the component will deduce it.

04:55.440 --> 04:59.970
And that may not seem very interesting, but in the next video, I will give you an example where this

04:59.970 --> 05:01.320
is actually rather useful.

05:02.340 --> 05:02.640
Okay.

05:02.640 --> 05:03.690
So that is it for this video.

05:04.110 --> 05:04.980
I will see you next time.

05:04.980 --> 05:07.470
But until then, keep coding!
