WEBVTT

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

00:00.960 --> 00:04.920
In this video, we are going to look at the duration types in the chrono library.

00:06.160 --> 00:10.650
The chrono header defines some integer types, which represent units of duration.

00:11.220 --> 00:13.770
These are in the std::chrono namespace.

00:14.880 --> 00:17.130
These are used for measuring time intervals.

00:17.490 --> 00:22.470
We have hours, minutes, seconds, milliseconds, microseconds and nanoseconds.

00:23.250 --> 00:27.000
And C++20 also has days, weeks, months and years.

00:30.360 --> 00:33.990
These are default-initialized, just like built-in integer types.

00:34.290 --> 00:39.480
So if we have a duration variable which is not initialized, then its value will be undefined.

00:40.530 --> 00:42.840
The constructor takes a single argument.

00:43.200 --> 00:48.300
So hours with an argument of 5 represents a five hour interval, and so on.

00:50.790 --> 00:57.850
In C++14, the library provides suffixes for these units. So we can have literals, which represent 5

00:57.850 --> 00:59.640
hours, 10 minutes, and so on.

01:00.120 --> 01:02.880
These are in the standard literals namespace.

01:06.010 --> 01:09.040
These duration types cannot be printed out directly.

01:09.340 --> 01:12.100
There is no overload of the left shift operator.

01:12.910 --> 01:17.590
Instead, there is a count() member function, which returns the numeric value of the duration.

01:18.070 --> 01:25.180
So if we have an object which represents 2 seconds, then the count() member function will return 2. Normally,

01:25.240 --> 01:26.950
You should not need to use this.

01:27.310 --> 01:28.950
It's there for doing output.

01:29.290 --> 01:35.080
And also, if you want to work with code which still uses the old, C way of doing things.

01:36.640 --> 01:37.840
So let's try this out.

01:38.620 --> 01:40.300
We include the <chrono> header.

01:40.630 --> 01:45.120
We use the std::chrono namespace and the std::literals namespace.

01:45.130 --> 01:48.730
If we are using the literals with the user-defined suffixes.

01:50.020 --> 01:53.140
We defined a seconds object, which is uninitialized.

01:53.620 --> 01:56.170
Then we print out its value. Which might be interesting!

01:57.340 --> 02:03.730
Then we create some duration variables, like the ones on the slide, and then we call their count() member

02:03.730 --> 02:05.290
functions and print out the result.

02:05.980 --> 02:07.090
So let's see what we get.

02:09.100 --> 02:11.950
So yes, that is definitely undefined.

02:12.790 --> 02:14.680
But the others all work as we would expect.

02:16.700 --> 02:20.690
We can perform all the normal integer operations on duration types.

02:21.080 --> 02:23.210
So for example, we can add them and subtract them.

02:24.470 --> 02:25.670
So let's see what this does.

02:27.380 --> 02:31.010
So if we add 2 seconds and 3 seconds, we get 5 seconds.

02:31.580 --> 02:37.190
And then, if we add another 43 milliseconds, we get 5043 milliseconds.

02:37.730 --> 02:41.180
So the result will be of the right type to store the data.

02:44.430 --> 02:46.590
The duration constructor is explicit.

02:46.860 --> 02:52.740
So, for example, we cannot implicitly convert from an integer to a seconds variable.

02:53.310 --> 02:58.500
We have to use a seconds literal. And this also applies to the conversion operators.

02:58.860 --> 03:04.260
So if we have a function which takes a duration type as an argument, then we cannot pass an integer

03:04.260 --> 03:04.740
literal.

03:05.250 --> 03:08.270
We have to pass a literal of the right duration type.

03:08.910 --> 03:16.290
So this prevents scenarios like the Mars lander fiasco, where the call thought that a literal number

03:16.350 --> 03:20.130
represented one unit and the function actually used a quite different unit.

03:23.460 --> 03:24.900
So let's try this out.

03:26.550 --> 03:30.980
If I call this function with a seconds literal, the function takes a seconds argument.

03:31.470 --> 03:32.280
So that works.

03:35.100 --> 03:37.410
If I try to call it with an int literal.

03:40.280 --> 03:41.870
Then there is a compiler ever.

03:45.710 --> 03:47.480
Constructor is declared explicit.

03:50.200 --> 03:56.260
If we want to convert between duration types, we can do this implicitly, provided there is no loss

03:56.260 --> 03:56.770
of data.

03:57.610 --> 04:03.580
So for example, one hour can be converted to seconds, because an hour is 3600 seconds.

04:03.940 --> 04:04.740
And that can be stored

04:04.750 --> 04:05.250
exactly.

04:06.400 --> 04:11.790
If we want to convert 5043 milliseconds to seconds, then we cannot do that

04:11.800 --> 04:12.340
exactly.

04:12.670 --> 04:14.800
And that would cause some data to be lost.

04:15.220 --> 04:16.180
So that is not allowed.

04:17.170 --> 04:22.570
If we want to do that, we have to use an explicit conversion, to say that we do not care about losing

04:22.570 --> 04:24.340
these 43 milliseconds.

04:25.030 --> 04:26.530
We do a duration_cast.

04:27.310 --> 04:33.100
The type that we are converting to is the parameter, and the value that we are converting from is the

04:33.100 --> 04:33.610
argument.

04:34.090 --> 04:41.740
So this will convert 5043 milliseconds to 5 seconds. And incidentally, if you have a negative argument,

04:41.980 --> 04:43.690
it is truncated towards zero.

04:44.110 --> 04:47.320
So this would give -5 seconds, and not -6.

04:49.270 --> 04:50.470
So let's try this out.

04:50.950 --> 04:58.420
I'm conversing one hour to seconds, and then casting 5043 milliseconds, plus and minus, to seconds.

05:01.060 --> 05:01.930
So there we are.

05:02.200 --> 05:08.410
One hour is 3600 seconds. 5043 milliseconds is converted to 5 seconds.

05:09.430 --> 05:11.680
If I try to do this without the cast,

05:15.270 --> 05:18.270
then there's a compiler error. Cannot convert...

05:19.920 --> 05:20.370
Okay.

05:21.400 --> 05:22.780
So that is it for this video.

05:23.050 --> 05:23.920
I will see you next time.

05:23.920 --> 05:26.320
But until then, keep coding!
