Hello again!
In this video, we are going to have a practical on perfect forwarding.
We are going to write a slightly more realistic example.
We are going to use this class.
It has one member, which is a library string.
It has two overloaded constructors which take a string, one for an lvalue and one for an rvalue.
We're going to make a function which will create objects of this class.
So this is a very simple version of make_pair(), if you like, or perhaps it should be make_single! In
this make_test() function,
we want to make sure that the move constructor is called whenever possible.
So we are going to use perfect forwarding to achieve that.
Our make_test() function is going to have a forwarding reference argument, and then it is going to call
the constructor for the class. And it will use the library forward() function to make sure that the appropriate
constructor is called for the argument type. And then we return this object by value.
It may look as though we are introducing an extra copy operation here, but modern compilers should be
able to optimize this away.
And in fact, in C++ 17, they are required to elide
that copy constructor call.
So this is going to be very efficient, we hope.
Let's look at the code.
We have our class here with the string member, and the two overloaded constructors.
Then we have our make_test() function which takes a forwarding reference.
It calls the constructor for the class, and it uses the library forward() function to call the lvalue
or the rvalue constructor as appropriate, and then we return it by value.
In the main() function we call this make_test() function with an lvalue argument, and then with an
rvalue argument.
So let's see if this works.
So, calling with an lvalue argument calls the constructor which takes lvalue, and calling with an rvalue
argument calls the move constructor.
So that works.
I've also put in these functions similar to the ones we had before, which will tell us what type
the arguments to make_test() is.
So let's call those.
So with the lvalue arguments, we get the modifiable version.
So that is an lvalue. And with the rvalue argument, we get the move version.
So x is actually an rvalue in here.
So this may seem a bit pointless.
Why not just call the constructors directly? And with this class you can do that.
It just has one member.
So there's only two possible constructors. With the pair class,
there is two members, which means there is four combinations of constructors. And also the members
are template types.
So you'd be using templates anyway, and this approach would make more sense.
C++ now has a few more functions which will make objects of library classes.
We are going to meet a couple of them in the next section, with "smart" pointers.
So that is why I'm going into this now.
Okay, so that is it for this feature.
I will see you next time.
Until then, keep coding!