WEBVTT

00:02.900 --> 00:06.860
Hello again! In this video, we are going to look at the auto keyword.

00:08.720 --> 00:11.210
The auto keyword goes back to C.

00:11.630 --> 00:17.360
Originally, it meant that we want the memory used by a variable to be managed automatically, which

00:17.360 --> 00:19.700
means a local variable on the stack.

00:20.930 --> 00:25.790
Then people got tired of watching auto every time they defined a local variable, so it became optional

00:26.150 --> 00:27.650
and eventually fell out of use.

00:28.610 --> 00:31.610
More recently, C++ has recycled the keyword.

00:32.060 --> 00:38.630
So now, when we say that a variable is auto, it means that we want the compiler to work out what type

00:38.630 --> 00:41.300
to use, based on the initial value that we give.

00:42.260 --> 00:49.340
So for example, if we have 'i' declared as auto with an initial value of 42, the compiler will look

00:49.340 --> 00:50.120
at 42.

00:50.750 --> 00:55.470
It's a literal of type int, and the compiler will deduce that i needs to be an

00:55.820 --> 01:02.330
int for this to work. If we have a C style string, the compiler will deduce that it's an array

01:02.330 --> 01:10.250
of const char. If we have a standard string literal, then the compiler will realize that we need a

01:10.250 --> 01:15.980
standard string object and it'll pass this initializer as the argument to the constructor for the string.

01:16.850 --> 01:19.070
So there are no temporary objects involved.

01:19.070 --> 01:21.380
There are no implicit conversions.

01:22.310 --> 01:26.570
The compiler will always use the exact type that's given by the initializer.

01:30.660 --> 01:35.400
So that may not seem terribly interesting. Something that might be a bit more interesting is we can

01:35.400 --> 01:37.950
use auto to simplify complex types.

01:38.490 --> 01:41.370
In the last video, we were writing out iterator types in full.

01:41.430 --> 01:49.080
So vector of int double colon iterator. Now that we know about auto, we can just put auto and the compiler

01:49.080 --> 01:49.890
can work it out.

01:50.460 --> 01:56.730
The compiler will know that begin() returns an iterator to whatever type vec is and the compiler

01:56.730 --> 01:58.860
will know that vec is a vector of int.

01:59.580 --> 02:02.730
So the compiler will know that "it" is an iterator to a vector of int.

02:05.470 --> 02:10.300
Another useful feature is that sometimes, for example, in template programming, it's not always

02:10.300 --> 02:13.600
easy to work out exactly what the type is. Or if you can work it out,

02:13.600 --> 02:13.930
it's not,

02:14.500 --> 02:16.660
it's not always easy to type it accurately.

02:17.350 --> 02:20.020
So putting auto can save you a lot of trouble.

02:21.460 --> 02:27.280
And then finally, as we'll see later on in the course (another teaser!), there are some situations in

02:27.280 --> 02:30.280
C++ where you can't actually know what the type is.

02:30.760 --> 02:36.700
So the compiler can actually create classes which have a type which is defined by the compiler.

02:37.270 --> 02:39.250
So you can't actually find out what the type is.

02:39.850 --> 02:41.800
So using auto is the only way.

02:42.100 --> 02:47.170
Well, actually, there is one other way, but using auto is the best way to handle it.

02:51.390 --> 02:52.620
So here's an example.

02:53.040 --> 02:53.920
We have our

02:54.940 --> 03:01.510
variables from the first slide. So i with a value 42 and the C-style and standard string

03:01.510 --> 03:07.840
literals. Then we're going to multiply i by two just to prove that it is at least a number of some kind.

03:09.100 --> 03:13.150
And then we're going to use this auto for the iterator, the iterator to the string.

03:13.540 --> 03:19.510
So we're going to call begin() to get the first element of this string. And then the iterator returned

03:20.020 --> 03:25.330
will have its type deduced by the compiler and then we can dereference that iterate and find out if

03:25.330 --> 03:25.990
it got it right.

03:29.990 --> 03:37.550
So there we are, i times two equals 84, so it has worked out that i is a number and not a string or

03:37.550 --> 03:38.210
some other type.

03:38.780 --> 03:40.910
And then the first element of str2 is 'H'.

03:41.450 --> 03:42.380
So this has worked.

03:42.600 --> 03:47.840
The compiler has got the correct type for the iterator and it's been able to dereference it.

03:53.130 --> 03:58.440
So we said that auto doesn't perform any kind of temporary objects or type conversion.

03:58.800 --> 04:02.100
It also doesn't take into account to const or reference.

04:02.280 --> 04:06.630
So it really does literally just give the type that's required to make the initializer work.

04:10.480 --> 04:15.310
So let's say we have a variable x, which is a reference to const int.

04:15.970 --> 04:20.950
Then we have another variable y, which is declared auto and initialized from x.

04:21.520 --> 04:23.560
So what do you think the type of y will be?

04:24.400 --> 04:26.440
And there's a big hint here if you need it!

04:28.800 --> 04:34.350
And now that we've defined y, are we allowed to modify it? So

04:35.740 --> 04:37.360
pause the video and have a think about this.

04:41.290 --> 04:42.610
Okay, so here's that code.

04:43.240 --> 04:47.950
So we're going to print out the values of x and y to see what happens.

04:48.340 --> 04:50.320
So first of all, let's see if it compiles.

04:52.540 --> 04:55.720
Yep, it compiled. I actually compiled it earlier,

04:55.780 --> 04:56.740
which is why it's so fast!

04:58.420 --> 05:02.000
So y is not actually a const.

05:03.730 --> 05:05.010
It's just a normal int.

05:05.590 --> 05:08.680
And then as it's a normal int, we can increment it.

05:11.020 --> 05:15.190
And then because y is not a reference to x, it is going to be value initialized, so it's actually going

05:15.190 --> 05:18.470
to be a copy of x, so it's going to be an int with initial value 6.

05:19.120 --> 05:23.860
And then if we increment it, the value of y will then be seven.

05:24.610 --> 05:27.010
And as that's a copy it doesn't affect x.

05:27.010 --> 05:28.660
So x is still 6.

05:35.090 --> 05:36.200
So there's the solution.

05:37.600 --> 05:43.620
The const and reference qualifiers are ignored, so auto y equals x is equivalent to saying int

05:43.630 --> 05:49.480
y equals x and then y and x are independent variables. y is not const, so we can just modify it

05:49.480 --> 05:56.320
and it won't affect x. If we do want to make y a const reference, then we need to actually add

05:56.320 --> 05:58.090
the const and the reference ourselves.

06:02.610 --> 06:06.900
So why is a reference to const whatever-the-type-of-x-is.

06:10.460 --> 06:14.210
And then we get a compiler error. You cannot assigned to a variable that is const.

06:14.660 --> 06:16.130
So now why is const.

06:22.120 --> 06:26.770
And we don't just have to use literals or variables. We can also use the return value from a function.

06:27.280 --> 06:29.050
So we have a function that returns five.

06:30.970 --> 06:34.120
And then we can initialize x with the return value from this function.

06:34.540 --> 06:37.870
So this function will be returned int, so x will have type int.

06:41.230 --> 06:43.210
So is autoo really that good?

06:43.300 --> 06:48.760
Is it something you should use all the time? And there are some very respected people in C++ who say

06:48.760 --> 06:51.280
that you should use auto in every single declaration.

06:53.250 --> 06:54.150
I don't agree with that.

06:54.570 --> 07:00.020
And a lot of people don't, in fact. There are also some people who just don't like auto at all.

07:00.030 --> 07:01.970
They say, "Oh, it makes your coat hard to read.

07:02.340 --> 07:05.760
"You have to keep looking at what everything does to find out what the type is."

07:06.390 --> 07:12.360
And there is actually quite a lot of truth in that. The type of an object gives you a lot of useful information

07:12.360 --> 07:16.260
about what the object is and what it can do and what you can do with it.

07:16.740 --> 07:22.770
So if you use auto, you remove all that information from the source code. So that can be quite a

07:22.770 --> 07:23.090
loss.

07:23.490 --> 07:26.100
On the other hand, there are some situations where it is useful.

07:26.850 --> 07:33.210
So, for example, if the type is not interesting or doesn't matter at all. If the type doesn't provide

07:33.210 --> 07:35.760
any useful information to the person reading the code.

07:37.630 --> 07:41.050
Generally, the best time to use auto is when it makes the code clearer.

07:41.590 --> 07:45.100
So I would say that the iterator is a good example of all the three.

07:45.790 --> 07:47.890
You don't really care what kind of iterator it is.

07:48.150 --> 07:50.260
It's an iterator into this vector. That's all you want to know.

07:52.120 --> 07:55.420
And I think there's that code is much clearer than that code.

07:57.140 --> 07:59.290
But, OK, it's a matter of opinion.

08:00.960 --> 08:06.720
If it's difficult to discover the [type], then certainly auto can make template cods a lot easier

08:06.720 --> 08:07.230
to read.

08:08.340 --> 08:10.530
And there are some situations where you have no choice.

08:10.920 --> 08:15.030
If you have a class which is generated by the compiler, you can't find out what the name is.

08:15.480 --> 08:16.740
So you have to use auto.

08:21.010 --> 08:27.220
Some situations where you should definitely not use auto. If you want to have a particular type. Because

08:27.220 --> 08:33.610
it's possible that auto might not pick the one you want. The rules that the compiler uses for

08:33.610 --> 08:38.920
working out what type something is can get pretty complicated, and it's not always easy for humans to

08:39.730 --> 08:42.070
get the same solution that the compiler does.

08:42.400 --> 08:47.560
So if you really want a particular type, then you should just put it in there, and not rely on hoping

08:47.560 --> 08:49.030
that the compiler will do the right thing.

08:49.780 --> 08:53.320
And also, if auto makes the code less clear, then don't use it.

08:53.950 --> 08:55.460
For example, some code like this.

08:55.460 --> 09:00.130
I mean - I have no idea what 'h' is supposed to be in that code.

09:01.180 --> 09:06.250
Admittedly, these variable names are very badly chosen. h doesn't tell you anything on its own.

09:06.670 --> 09:11.890
Maybe it makes more sense in the context of a program, but I would definitely want to have the information

09:11.980 --> 09:15.940
that the type gives here, so that's somewhere I would not use auto.

09:17.470 --> 09:17.860
Okay.

09:18.760 --> 09:21.070
So there we are, a bit of food for thought.

09:21.160 --> 09:22.660
Some controversy at the end of this one!

09:23.560 --> 09:24.550
I'll see you next time.

09:24.550 --> 09:27.310
But meanwhile, keep coding.
