Containers in c++
Published: 2023-09-05 13:35:19

# Containers

Containers are used to store objects of the same type and provide operations with which these objects can be managed. These operations include object insertion, deletion, and retrieval. Memory is allocated for containers dynamically at runtime. Containers thus provide a safe and easy way to manage collections of objects

The C++ standard library provides various class templates for container management in the Containers Library. These classes can be categorized as follows:

- **sequential containers**, or sequences, where the objects are arranged sequentially and access to an object can either be direct or sequential
- **associative containers**, where the objects are generally organized and managed in a tree structure and can be referenced using keys.

<br><br>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ync4yljb8odmssdzsyu9.jpg)

## Sequences

Sequential containers are distinguished by the operations defined for them, which are either generic or restricted. Restricted operations, such as appending at the end of a container, have constant runtimes. That is, the runtime is proportional to a fixed period of time and does not depend on the number of objects in the container.

The following are sequential containers:

- **arrays**, which provide the same operations as C arrays but increase and decrease in size dynamically, in contrast to C arrays
- **queues**, which are managed on the FIFO (First In First Out) principle. The first element to be inserted is also removed first
- **stacks**, which are managed on the LIFO (Last In First Out) principle. The last element to be inserted is removed first.

## Associative Containers and Bitsets

Associative containers comprise sets, which allow quick access to objects via sortable keys, and maps, which maintain efficient object/key pairs.
There are also so-called bitsets, which represent bit sequences of a given length and provide bitwise operators, with which bits can be manipulated.

## Representing Sequences

- The container **class vector<T, Allocator>** supports standard array operations, such as direct access to individual objects via the subscript operator [], and quick appending and deletion at the end of the container.
- The container **class list<T, Allocator>** provides functionality that is typical for double linked lists.
- The container **class deque<T, Allocator>** provides direct access via a subscript operator, just like a normal array, but offers optimized insertion and deletion at the beginning and end of the container.

The second template parameter **Allocator** is used for any storage allocation to be performed.The default value of the template parameter **Allocator** is the standard allocator class **allocator<T>**.

## ITERATORS

Each object in a container occupies the specific position where it was stored. To allow you to work with the objects in a container, the positions of the objects in the container must be accessible. There must therefore be at least one mechanism that allows:

- read and/or write access to the object at any given position and
- moving from the position of one object to the position of the next object in the container.

**Two types of iterators**

- **_bidirectional iterators_**, which can be shifted up by the increment operator ++ and down with the decrement operator -- .
- **_random access iterators_**, which are bidirectional iterators that can additionally perform random positioning.

**example**

```c++
#include <list>
typedef list<int> INTLIST;
int display(const INTLIST &c){
    int z = 0;
    INTLIST::const_iterator pos;
    for (pos = c.begin(); pos != c.end(); pos++, z++){
        cout << *pos << endl;
    }
    return z;
}
int main(int argc, char const *argv[]){
    INTLIST intList{1, 3, 4, 67, 876};
    cout << display(intList);
    return 0;
}
```

## Constructors of vector, list, and deque

The container classes vector, list, and deque define three constructors and a copy constructor with which sequences can be created.

The statement

> > vector\<int> v;

declares an empty container v for objects of the _int_ type. You can then insert individual objects into the container. However, you can also declare a container and fill it with a predefined number of object copies.

**Example** vector<int> v(100 , 10);

This defines the container **v** with 100 int type objects, and fills it with the value 10.

you can initialize a container with a part of another container. To do so, you
must state a range of iterators.

> > Example: vector<double> v( first , last );

The arguments _first_ and _last_ are iterators in an existing container.

### INSERTING IN SEQUENCES

---

| Method                      | Effects                                          |
| :-------------------------- | :----------------------------------------------- |
| void push_back(const T&x);  | Adds x at the end of the sequence.               |
| void push_front(const T&x); | Adds x before the first element of the sequence. |
| insert()                    | insert after a given position.                   |

### ACCESSING OBJECTS

Access to individual objects in the container classes vector, deque, and list can be performed by the following methods

|         |                                 |
| ------- | ------------------------------- |
| back()  | for access to the last element. |
| front() | for access to the first element |
|         |                                 |

    Example: double z = v.front();
             v.front() = 1.9;

The subscript operator [] is overloaded in the vector and deque classes to permit the use of indices for access to the objects in a container.

    Example : v[20] = 11.2; // the 21st object

### Length of a Container

The length of a container is discovered by a call to the size() method.The method returns an integer of the **size_type** type.

You can also use the empty() method to discover whether a container is empty.