Standard Library Support for Movable Types

Packt Publishing
A free video tutorial from Packt Publishing
Tech Knowledge in Motion
3.9 instructor rating • 1411 courses • 332,007 students

Lecture description

Understand the benefits of writing movable classes in relation to facilities provided by the Standard Library

Learn more from the full course

Mastering C++ Standard Library Features

Harness the power of the C++ STL and make full use of its components

06:12:38 of on-demand video • Updated January 2018

  • Analyze and demystify some major new features such as move semantics, variadic templates, and lambdas
  • Learn about new core language features and the problems they were intended to solve
  • Discover new techniques that allow computations to be performed at compile-time
  • Create safer and more convenient interfaces, without any extra hidden cost
  • Improve your code by replacing new/delete with smart pointers
  • Get well versed with the C++ STL and make full use of its components
English [Auto] Creating mobile clusters in this section we're going to take a look at the recent cluster immovable item and placement in standard containers how to write classes that benefit from move semantics to rule 5 and Unruh of zero. And lastly we're going to have an example implementation of a bare bones movable anywhere where a city vector aplomb at the beginning of the first video sándor library support for mobile types in this video. We're going to take a look at the benefits of making or causes movable and some of library utilities that work revolve around movable user defined types. Begin by answering the questions why would you make your test mobile and where would use an effort on it. Writing classes that support operations can greatly increase performance safety expressiveness of your code as we've seen in previous sections. Also this is a topic we're going to cover in this video. The center library provides many utilities that make use of move semantics or are defined in terms of semantics even for user defined types as having to decode almost every continent. The library is aware. This means that it will use mouthfull permissions if available when dealing with his items. Let's begin by looking at a city vector assuming that foo is one of your classes that supports move semantics we can see the vector will try to whenever possible in order to prove this cheaply. I have added some print statements in the constructor destructor and copy and move operations of the class in the first function Bactrim of awareness will begin based on hitting a vector of Foo. And as for instance a 0 on the stack Thursley will push back as Sirin said a vector and this will obviously keep it. If we use a C D move will convert f 0 to on our value reference and pushback will detect it and move f 0 inside the vector. The same will happen if you use pushback on a few temporary. It will be moved as it's not ready. An r value. Let's start to compile this snippet and look at the output before doing that. Let's reserved the vector so that the internal by resizing doesn't produce additional interesting operations the output is what we expect. We see a copy when pushing back at 0 a move when pushing back. Using a CD move and then a temporary being constructed and a move when pushing back a temporary inside side vector. Finally every instance we created is destroyed. Let's not introduce a new concept. The concept of and placement center library containers allow us to go one step further. Compared to moving items inside containers and allow us to and try to reconstruct two items in place inside the containers. This operation is called and placement is supported by most standard library containers. Here's a simple class called Bar which contains in each member field and a constructor that takes an int initializes its member in its function. Veteran placement we concentrate a vector bar. Then we're going to move the bar temporary and say the vector using pushback then we're going to use this new member function and through diciples 11 which is called and placed back which takes any amount of arguments and perfect force them to parse construct or which will construct a BART instance in place we should be able to see that there is no move happening Fortean placed back call as the bar instance is constructed directly and said the victim in order to show the effects of them placement when running this code snippet. Let's first start some print statements to the bar operations. Also as we did before let's reserve some memory for the vector. So the internal buffer resizing won't affect the output of our program. We can now run our program and will see something really interesting. When calling pushback as expected there's going to be a call to the bar constructor taking moment and then to bar instance it's going to be moved inside the vector but when calling in place back we will see any move or copy operation. This proves that the bar instance has been constructed inside the vector and placement works by perfectly forwarding all arguments passed to then paste back the member function to the constructor of a bar instance that's being created directly in the target memory location inside the vector. Note that writing a where removable Custers is very important even if emplacement exists. Consider the case where we have a bar wrapper struct which is self-containment bar and has a constructor using the pass by value and move idiom to any shots its member bar variable. In this example function over here we are creating a vector of bar wrapper and then and policing back abart instance into it. Unfortunately the code above there is no way that we can avoid the bar temporary from being constructed and moved inside the wrapper. This example shows that when you have more layers of indirection or wrappers such as in the case of bar wrapper it is beneficial to have more permissions even if some place back and similar method exist as you don't know how your class is going to be used and providing the best possible code for copy and move operations. It's important to ensure the performance of your program vector is obviously not the only container or support team. Move semantics. Older commonly used to library containers or move elsewhere and support and placement. More Examples include a city map a city set a city list a city and an order set for list. And many more containers are not the only important thing that a Senate library provides which heavily relies on semantics. The Senate library provides many utility function and classes which are defined in terms of move semantics or heavily support them. Some common utilities that you might use before like Cassidys wup or some new utilities such as the exchange are defined in terms of semantics generic Ruppert such as the steady pair or CD tuple will use move semantics whenever possible and even algorithms can benefit from that semantics tensity efficient of things like move iterator which Rupp's an existing iterator forcing it to move on Evista. Let's switch the editor could take a loop of everything I just mentioned. Speaking with swap swap is a very versatile way it was swapping two objects. Users can to find their own pixelization that can be found through a yell but a swap is always a valid fallback before it was plus 11 as it is what it was typically defined as follows. It will copy the first one to a temporary object then assigned the value of the second one to the first one and finally assign devolved to temporary object to the second one. This works but is incredibly expensive for a lot of types which lead containing Putman patients to provide their own tasks what puzzles patients plus Lemon in a bowl swap is fine in terms of semantics. You can see that this is very similar to the previous implementation but instead of copying at times he will attempt to move through times when possible copies are executed when using a default implementation of a CD as. Since most of us 11 and these great both library users and developers as long as you provide sensible move operations for types as well will be automatically efficient. Take a look at a new utility added Antipas plus 14. It is called Exchange and what it's similar to swap does a completely different role. The signature of exchange is as follows. Use a template function that takes a t in a U which is the 1:46 you will take an object by OBALI reference and a new value by 40 reference. Finally it will return a new instance. The semantics of the exchange are as follows. It will replace object which is the first argument with the new value while returning the old value of object relies on a new supporting move operations. Here's a possible implementation in these simple implementation. The first thing we do is to temporarily store the old value of object inside old value temporary viable. In this case we use move to prevent them Asare copies then we use a city forward to perfectly forward and involve you inside object. Again if your values and our value will move instead of copying and finally we returned a sort of value. Since we are returning a local variable This will probably trigger RVO return value proposition. But even if it doesn't it will just move deal value out of the function. As you can see from this implementation if both Tiant you implement efficient mover operation as in exchange is a very cheap way of modeling replacement. Where did these values interest the most common use case for a city exchange is when implementing corporation for these different types I think it's all boilerplate. This is another barebones unique pointer implementation. Which is obviously not complete. And he's here just for educational purposes as you can see stores a pointer to an int which is by default initialized not pointer. It provides a constructor that would take ownership of an existing int pointer and the destructor will automatically delete it for copies are prevented by deleting a copy constructor and copy assignment operator. Now you can see how the exchange is really useful in making the code more readable. Terser when dealing with move semantics the move constructor or unique pointer will change its own stort internal pointer to the great insights pointer and we also set the right insights pointer with NULL pointer to prevent the memory from being fried twice and a Exchange captures the semantics of this operation very elegantly. As you can see from this line of code the first thing we do is to store the first value here which is the run and said pointer to some temporary location in memory. Then we assign no pointer to the right and type pointer so that it will not be freed twice. And finally we assign the right inside pointer value to member P viable so that the current unique pointer will take ownership of the memory location. With exchange we can say that in one line without repeating ourselves and this can be useful both for the constructor and for the move assignment operator. One way of quickly remembering what exchange is doing is to look at it as a series of operations that are being executed left to right. You should read this line of code from left to right. You can see that P is going to take the value of r h s that P and R it just that P is gonna take the value of a null pointer. So that's a quick way of remembering the function of the exchange. That's not louca some generic wrappers. You'll probably use either pair or tuple in your code before they are general purpose repurchases that bundled together object of potentially different types. A city pair is just like tuple but is less general as it only holds two elements. So for the rest of this code snippet we're going to call the coupal all observations which also play to pair tuple instances can be created explicitly but these inner constructor or fusee the make tuple which is a utility function that uses the type of diopters for you. Moves are used whenever possible both during construction and assignment dysfunction. Creating and assigning we're going to look at some examples of creation and assignment of tuples to first tuples The zero is created by explicitly specifying its type. It will be a tuple containing a food a bar and then int by using uniformly salvation we are the full construct into foo. The bar and constructing the into with one the second tuple T-1 will be constructed by using a CD make tuple which takes any amount of arguments and returns a new tuple with the types to use from the arguments you pass to make tuple. In this case the result in tuple will have the same type of zero a tuple a full bar and int tuples can be copied using the Semon operator and this will execute an element Weist copy. They can also be moved by using a CD and it will execute an element wise. You can retrieve items out of tuples and pairs using a city get a city get allows you to retrieve items either by index or by type. Let's begin by looking at the retrieval by index in this function. I'm creating a tuple named T which contains a fool a Barton on it. I can retrieve l value references to the items inside a tuple but using a city get and specifying the index of the item I am interested in as a template argument. As an example if I say the get of 0 of T I will get back Kaanapali reference to the first item which is a full. I can also move items out of a tuple in two different ways. I can use any get and then move the result of that function call to get an honorable reference. Two of the items of the tuple or I can move the whole tuple and then use this to get on the r value reference of the tuple generated by a city. Both of these techniques were moved items out of a tuple. The first one allows you to decide which items you want to move. But you need to be careful in order to maintain the tuple about state. The second one will instead cast the entire tuple pointer by reference as city get. Has an overload for the reference to tuples. We moved the item out of the tuple since it was just 14. As I previously mentioned a get also supports retrieval by type. If a tuple has no duplicate types use example function. I am again creating a tuple containing a food bar and int and then I am using city get passing int as a template argument and it will automatically find the position of the item and set the tuple and return an invalid reference to it. If the tuple had duplicate types a city get would cause a compiler error. Tuples can also be structured by using the assiduity utility function is particularly useful when the function returns a tuple. In this particular example the get t function returns a tuple containing a fool and a bar. Let's now assume that I already have an instance of foo in an instance of bar in my scope and I want to assign Bohu them at the same time to the result value of get t. This can be easily done using a city type SD type a utility function that takes any amount of non-const value references what it returns is simply a tuple. Better references. SETI is a utility that given an arbitrary amount of non-causal value references will produce a tuple of references from its arguments. In this case calling a city type with F and B will produce a tuple of 4-F and Bharath get t to do Salten tuple of references produced by city TEI will perform element y is assignment from the food and bar instances returned from T to the ones pointed by the references into a city type tuple. The return tuple will then be assigned to the result of T so that every object pointed by the references will get its final result from the value returned by the function note what the objects will be moved out of the source tuple if it is an our value since you were 17. We also have a new function called a city of play which can be used to invoke a function with the elements of a tuple. And again objects will be moved out of the tuple with other bits as an example. We have a very simple add function that takes two integers and returns or some. Let's assume that we have a tuple containing to integers and we want to call add where the elements of the tuple is what acidy apply exactly allows us to do the first argument was that the apply is the function object that we want to invoke. The second argument is a tuple what is to be applied does is basically an pucca tuple for us and then perfectly forward. The elements of the tuple to the function object was specified and called it for us. So in this case if you have a tuple containing 1 and 2 and we call the apply with ADD and that tuple what we get back is free because it is being called with the cons of the tuple. Similarly the standard library sensible poster that team provides other utility which is called Make from tuple which can be used to construct an object with the parts of a tuple. Let's assume we have a class called foobar that can be constructed from a. And a bar instance. And let's assume that we have a tuple that contains a food and a bar instance. If we want to build a foobar instance of the tuple we can use a city make from tuples specifying the type of the desired object as a template argument and then pass it on tuple. These again were basically undraped a tuple for us inside a constructor called to foobar. And then it will return a construct an instance of the class with desire tuples a very useful generic programming or we're writing code. They can also be used for quick prototyping or avoid boilerplate when a simple report is required. Additionally they support lexical comparisons which allow easy definition of by member comparison operators. Let's assume you've created a struct or a class which contains multiple data members. What you could do is simply write out every comparison or equality in quite you operator manually but that causes a lot of boilerplate and repetitive code. Instead you can use tuples to generate most of the code for you in this simple struct called to eans. I have to enter data members called a and b and the way I'm defining D or operator is by using a city type since a city type creates a tuple Velvel it references have no extra cost here. The creation of the tuple would be very likely optimize that way from the compiler and I can tie both the elements of the current instance and both the elements of the right inside instance and simply use the point to Prader on tuples to get the result to require. This can also be done with inequality and other kind of comparisons. Finally let's take a look at movie trailers. As you may know the center library provides a huge number of general purpose algorithms and the upgraded header. These algorithms must operate at any rate repairs so you move or where algorithms have been introduced and people a see them. These are a city move in a city move backward even though a city move shares the name with the commonly used utility. It also has its own algorithm which works and these rates are purse but most of the existing algorithms are unfortunately not move or where the solution to that is a city movie iterator and a city make moving to nature which have been added to the through header. These functions allow us to adapt existing iterators so that they move up on the referencing. Let's see an example here. I defined a very simple predicate called has five chars which takes a constant reference to a string and returns true if the string has only five chars in these function example copy. What will happen is that I will copy all the strings from the source vector to the station vector by using their city copy if algorithm CD copy if takes I need to arrange specifying the source and then an output iterator specifying that a summation. In this case the source is an iterator range of the source vector and that the situation is a back inserter and say the summation. It also takes a predicate and it will only copy the elements that match the predicate. In this case my predicate is has five chars. Look at this example. What we're doing is basically consuming the items inside source to create an extra called the summation theoretically we should be able to move from source of the situation to avoid unnecessary Capas. This is exactly what is needed. Make a movie allows us to do by wrapping the source iterators with a city make when we talk later. The objects that's satisfied has five chars predicate will be moved instead of copy. As you can see the code is very similar but instead of simply having begin and end of source you will have them wrapped inside the make moving troit to function call. And this will guarantee that the items Matuidi has five chust Pennicott will be moved from source to the summation. Let's recap what we're seeing in this video. Implementing move operations for your types allows your code to be faster safer and more expressive. The standard library provides a huge number of pool where containers and utilities which make use of move operation were possible and some of them rely and move operations motorcycle's plus libraries follow the steps of the summer library and will strive to provide more awareness. My advice is to always think about move semantics and move awareness when creating new types. You will not only have performance and efficiency benefits in normal usage but when using the sun or library or third party libraries it is very likely that the more pressure you find will be internally used by those libraries as part of their implementation in the next video. We'll start looking at how you can correctly find more for your costs by defining the rule of five and a rule of zero.