std::array : safe C arrays

The std::array was a new container introduced in C++11. A std::array works in the same way as a plain old C array (like int values[5]) but has the advantage that it will not decay into a plain pointer.

Unlike the vector can an array not be resized once it has been created.

Creating

std::array is always allocated on the stack. It it allocated using uniform initialization:

Iterating

You can iterate through each of the values in the array using range-based for:

or using std::for_each and a lambda

Facebookgoogle_pluslinkedinmail

std::map : The C++ dictionary class

std::map is the C++ standard library implementation of  a dictionary. It contains key-value pairs where the keys are all unique and the key values are used to find the associated values, much like a real-world dictionary. The map is, just like most of the standard library, implemented using templates and the types of the keys and the values are given when you create the map. Some examples of maps:

Each element of the map is of the type std::map<K, V>::value_type which is just a redefinition of std::pair<const K, V>.

Getting one element

To get the value associated with a specific key, use the bracket operator ([]). This operator will create the key-value pair if it doesn’t exist already.

Checking if a key exists in map

There are two ways to check if a key exists in a map.

  1. Using the function std::map::count(). This returns the number of keys which matches the queried key, and since all keys in the std::map are unique can this only be zero or one. This is a good way to do it if you just need to see if the key exists and don’t need to do anything with the map.
  2. Using the function std::map::find(). This returns an iterator to the found object, or std::map::end() if the object is not found. This is a better choice if you need to update the map, since you will get an iterator to the found key value pair.

Iteration

To iterate over all elements in the dictionary use range-based for:

or much simpler using auto

Notice that it is a good idea to make the variable in the loop a reference since this avoids copying the element and gives better performance. Also if you don’t intend to change the element then you can make this clear by also making it const.

Erasing one element

You can erase one element from the map by using the function erase(…) which takes either an iterator, a key or a two iterators defining a range of values to remove.

 

Facebookgoogle_pluslinkedinmail

std::vector

The std::vector is one of the must useful containers of the standard library. It stores an array of elements on the free store (the heap) one after the other, just like you would get if you allocated the memory using new[]. The std::vector is very handy since it is very versatile and easy to use. Being a part of the standard library it will also manage its memory for you (using RAII) which avoids the memory leak problem. Since the objects are allocated contiguously in memory is this possible to use in combination with old code which expects an array of elements.

Creating

std::vector is always allocated on the stack. It can be allocated using uniform initialization:

or using just the size:

It is possible to add elements to the vector one at a time using push_back;

however, pushing back elements at the end of the vector is not recommended if the vector should hold hundreds of elements or more. When you push_back an element to the end then the underlying array will occasionally be resized by allocating a new array and copying all the elements from the old to the new array and this is a very time consuming process.

Iterating

You can iterate through each of the values in the vector using the new range-based for (C++11):

or using std::for_each and a lambda

Number of Elements

Unlike a dynamically allocated array (allocated using new[]), you don’t have to keep track of the size of the vector. Get the number of elements in the vector by calling the method size()

See also: Converting std::vector to C array and back

Facebookgoogle_pluslinkedinmail

Unique Pointer – std::unique_ptr

With C++11 came a new smart pointer class, std::unique_ptr.

This is a great class to use when you need to allocate an object which must have a life time longer than the current local scope. In old C++, this would be done by creating the object on the free store using new. It would then be up to you as a programmer to decide when the object is no longer necessary and then call delete on the pointer. The new unique pointer frees you from remembering when to call delete. The key feature of the unique pointer is that is just that, unique. There can be one and only one pointer to the managed object and no copies can ever be made. If you need a pointer which can be shared between many classes then you should instead go for shared_ptr.

The unique pointer is stored on the local scope and when it goes out of scope then the contents of the pointer will be deleted.

Non copyable

The key feature with the unique pointer is that it is unique, this means that no copies of the unique_ptr can ever be made. This has as a side effect that an object which owns a unique_ptr as a member variable can itself not be copied. If you think about it, then this is actually the same behavior as in old C++ when you instead would create a pointer using new and store the pointer as a member variable in a class. That pointer caused problems when you tried to make copies of the owning object, because who should own (and then also delete) the pointer after the copy was made? The original object or the copy? In practice this made the object not copyable unless you explicitly wrote an copy constructor and copy assignment operator. The difference is that in the old way would the program still compile and run. Modern C++ stops you from doing this, it tries to stop you from shooting yourself in the foot!

 Movable

The unique pointer is on the other hand movable, this means that it is possible to create a unique_ptr inside a function and then return the created pointer. It also means that objects owning a unique pointer will themselves also be movable without you having to do anything.

Make

C++11 introduced the std::make_shared function which made it possible to create a shared_ptr safely and easily. However, the make_unique function wasn’t added until C++14 simply because of an oversight in the review. If your compiler supports C++14 then you can create the unique pointer like this

where the parameters to the constructor of the class are passed in the parenthesis

Facebookgoogle_pluslinkedinmail

Converting std::vector from a C array and vice versa

Sometimes it is necessary to interact with C code from a C++ program. We would then need to extract a pointer out from a vector, or vice-versa, create a vector from a pointer to data without having to worry about the extra memory management this may cause.

This one line of code will convert a pointer to an array and the number of elements in the array and into a vector from the C++ standard library:

This creates a copy of the data, so that when the local vector goes out of scope then the input pointer will not be deleted.

To get a C style array out from a C++ vector, use:

calling the method data() returns a pointer to the first element in the vector. This pointer must never be deleted, the vector will take care of cleaning up its contents.

Facebookgoogle_pluslinkedinmail