WEBVTT

00:00.090 --> 00:03.420
Hello again! In this video, we are going to look at the pair type.

00:04.230 --> 00:09.690
I have just added a couple of videos at the end of this section, with some things that we need to know about

00:09.990 --> 00:14.040
before we can go on and look at algorithms and containers in more detail.

00:16.430 --> 00:19.550
The standard pair type is defined in the <utility> header.

00:20.480 --> 00:24.710
It has two public data members, which are called "first" and "second".

00:25.310 --> 00:26.450
They can be of different types.

00:26.990 --> 00:29.600
And there are no public member functions.

00:30.080 --> 00:32.330
So this is rather an unusual type.

00:32.780 --> 00:36.620
I do not think there is anything else in the library which has a public data member.

00:38.000 --> 00:43.940
One use for this is, if you have a function which returns two values, you can return a pair object instead

00:43.940 --> 00:45.680
of having to define a struct.

00:47.780 --> 00:52.550
There are some containers in the Standard Library which use a pair to store their elements.

00:52.910 --> 00:54.980
So that is really why we are interested in it.

00:57.950 --> 00:59.720
The pair is a templated type.

00:59.930 --> 01:03.980
So when we call the constructor, we need to give the types of both the members.

01:04.610 --> 01:10.250
If we are creating a pair which has "Hello" as the first member and "there" as the second member, then we

01:10.250 --> 01:12.950
need to make this a pair of two strings.

01:13.850 --> 01:16.550
And once that has been created, we can access

01:16.550 --> 01:17.310
that, as "wordpair"

01:17.310 --> 01:18.710
dot "first" is "Hello",

01:18.980 --> 01:21.230
and "wordpair" dot "second" is "there".

01:23.690 --> 01:27.380
Alternatively, we can call make_pair() to create the variable.

01:27.740 --> 01:32.670
So we just give the first and second values as arguments, and the compiler can deduce the types from that.

01:33.650 --> 01:36.800
So we need to put the "s" suffix in here, to make sure we get strings.

01:37.310 --> 01:41.210
If we do not put that, then we will get arrays of char, which is different.

01:43.550 --> 01:52.420
And then we are just using that to initialize a pair object, and we can use auto there. In C++17,

01:52.430 --> 01:55.640
the compiler can deduce the types for a constructor call.

01:56.030 --> 02:00.440
So we can just put the arguments, without having the angle brackets.

02:00.740 --> 02:03.110
And again, we need to make sure we get the right types.

02:04.680 --> 02:11.390
So let's try that out. We have our constructor call here, and then we print out the first and second

02:11.400 --> 02:11.910
members.

02:15.340 --> 02:16.900
And we get "hello" and "there".

02:21.150 --> 02:24.600
We can also use make_pair() to create the object.

02:27.230 --> 02:27.830
"hello" and "there".

02:28.250 --> 02:31.670
And that is quite useful if you are returning from a function. You can just call make_pair() and then

02:31.670 --> 02:33.560
put the data that you want to return.

02:37.930 --> 02:43.180
And finally, you can use the C++17 form, which Visual C++ does not support.

02:43.570 --> 02:45.610
So let's try GCC.

02:49.240 --> 02:50.290
And yep, that does work.

02:51.700 --> 02:55.540
So let's look at an example of a function which returns a pair.

02:56.470 --> 02:58.300
So here is that function.

02:58.720 --> 03:03.900
It actually calls the lambda expression we had in the earlier video, but this time we have taken

03:03.910 --> 03:06.880
it into a separate function instead of putting it inside main().

03:07.930 --> 03:10.630
So this function will take the vector as an argument.

03:11.140 --> 03:16.840
And also the number of characters that we want the element to have. Then it will do this find_if() call.

03:17.320 --> 03:22.510
And this will calculate the index of the first string with more than that many characters.

03:23.830 --> 03:27.490
And then we can return the string and the index as a pair.

03:27.880 --> 03:30.470
We dereference the iterator, after checking that

03:30.470 --> 03:34.110
it is valid. If we do not get anything at all,

03:34.120 --> 03:39.610
we just return an empty string and the index of minus one will tell the caller that there's nothing

03:39.610 --> 03:39.850
there.

03:42.900 --> 03:49.620
So this returns a pair. We are using list initialization here, which is yet another way to create a pair!

03:52.050 --> 03:57.120
And then the main() function is all the same, except we have this call to the function, instead of calling

03:57.120 --> 03:58.260
find_if() directly.

04:01.700 --> 04:03.680
And there we are, we get "collection" and 1.

04:06.920 --> 04:13.850
We can also get a bit more up to date and use some C++14 and 17 features. So we can get this function to

04:13.850 --> 04:16.700
return auto instead of watching out the pair explicitly.

04:17.840 --> 04:19.250
I think that is probably a bit marginal.

04:19.520 --> 04:23.240
If we were turning an iterator as one of the elements, then that would be a good case.

04:23.240 --> 04:27.590
But this is possibly - well, it is up to you, really.

04:28.490 --> 04:34.040
And then we can use the C++ 17 constructor, which does not require the angle brackets.

04:35.780 --> 04:36.770
And the same code again.

04:40.870 --> 04:46.720
OK. Some of you might not be completely convinced by Modern C++. I mean, there is one or two nice things,

04:46.720 --> 04:48.970
but there is nothing really wrong with the old way of doing things.

04:49.600 --> 04:55.990
So I have written this out again, using C++ 03. Or 98, if you prefer, they are basically the same standard.

04:56.860 --> 04:58.680
So we have to use the functor.

04:58.720 --> 05:02.890
We have to write it out ourselves, because the compiler is not going to generate it for us.

05:03.340 --> 05:05.170
That is just the one we had in the previous video.

05:07.790 --> 05:12.650
Then we have to use this form of initialization, because brace initialization is not supported.

05:13.760 --> 05:18.980
We have to write out the iterator type explicitly, because there is no "auto" keyword.

05:20.360 --> 05:26.900
We have to use the memory function call to begin(), because there is no non-member function. And then

05:26.900 --> 05:28.490
we can call make pair.

05:31.150 --> 05:38.350
And then the - possibly the most painful bit or perhaps the iterator is the most painful, but

05:38.350 --> 05:42.760
having to type all this completely unnecessary code, really, when you are used to writing list initializers.

05:45.430 --> 05:51.340
Then again, we cannot use the auto keyword and we cannot use raw strings. Although maybe that is not a big

05:51.340 --> 05:51.970
loss in this.

05:52.300 --> 05:56.770
So you can see that some features are just slightly convenient. And some are very convenient!

05:59.350 --> 06:01.450
And then obviously, that works.

06:01.900 --> 06:03.700
Okay, so that is it for this video.

06:04.150 --> 06:05.040
I will see you next time.

06:05.350 --> 06:07.420
Until then, keep coding!
