Skip to main content

C++ Containers

There are a lot of different containers in C++. A container is a holder object that stores a collection of other objects (its elements). They are implemented as class templates, which makes them able to store almost any type of objects.

The container manages the storage space for its elements and provides member functions to access them, either directly or through iterators. This makes them much more powerful and safe than the plain old C-arrays.

Containers implements structures very commonly used in data science: dynamic arrays (vector), queues (queue), stacks (stack), heaps (priority_queue), linked lists (list), trees (set), associative arrays (map) and more. Each of these have their own characteristics.

C++ have a lot of containers, but in this series of articles we will first look at the characteristics of each of the four ones you probably will need in your toolbox:
  • std::list 
  • std::vector 
  • std:set 
  • std::map 

Today we will start with the list and later issues will handle the rest. We also will look at iterators.

The list


std::list is implemented as a double-inked list. A list allow insert and erase operations anywhere within the sequence, and iteration in both directions. The cost of growing the list is always constant time and memory.

The drawback with linked lists are that they add extra data for each element so the total storage will be larger than for a C-array or std::vector. So if you have long lists, they might be better stored as vectors to conserve memory. Another drawback is that lists don’t allow direct access to their elements, you will have to iterate through the container to find a specific element.

In the sample below you can see some of the features of std::list. We create a list of numbers, push numbers at front and back.

Then we use an iterator to point to an element in the list. The iterator is set by the find-algorithm. We will get back to the algorithms in STL (standard template library) in a later issue of this news-letter.

int main()
{
    // Create a list containing integers    
    std::list<int> l = { 7, 5, 16, 8 };
    // Add the integer 25 to the front of the list    
    l.push_front(25);
    // Add the integer 13 to the back of the list    
    l.push_back(13);

    // Insert 42 before 16 by searching    
    auto it = std::find(l.begin(), l.end(), 16);
    if (it != l.end()) {
        l.insert(it, 42);
    }
    // Iterate and print values of the list    
    for (auto element: l) {
        std::cout << element << std::endl;
    }
}

Iterators

A std::iterator is an object that, pointing to some element in a container). It also has the ability to iterate through the elements of that range using a standard set of operators for example increment (++) and dereference (*) operators. The syntax for the std::iterators in many ways works as standard c-pointers but with a lot more under the hood.

To iterate over a container with an iterator has two benefits: It is generic and works on all containers so if you change container type you don’t have to change your code. It is also guaranteed to be the most efficient form of iteration for the given container.

When should you use the C++ std::list?


The std::list is ideal for small datasets that change a lot, especially when you add things in other places than at the end. For larger datasets the memory-overhead could be too large to ignore. This is always compared to the size of the objects stored: Big objects might be expensive to move, which might be needed in other containers.

Comments

Popular posts from this blog

Evolution Of Programming Languages in an AI perspective

Programming languages are at the heart of possibilities in software development, evolving to meet the growing complexity of the problems we solve with computers. From the early days of machine code and punch cards to the modern era of high-level languages and AI-augmented coding, the journey of programming languages reflects humanity’s relentless pursuit of abstraction and efficiency. As artificial intelligence begins to reshape the landscape of software development, we are poised to enter an era of AI-powered programming languages—tools that will fundamentally change how programmers approach their craft. From Punch Cards to High-Level Languages The earliest programmers worked directly with machine code, encoding instructions in binary or hexadecimal formats. This labour-intensive process required an intimate understanding of the underlying hardware. Punch cards, though a technological marvel of their time, epitomized the low-level nature of early programming—tedious, error-prone, and ...

The Industrial Vs the AI Revolution

The transformation of society through technological revolutions has constantly fundamentally reshaped the labour structure. The Industrial Revolution, for instance, marked a profound shift in work for the labouring classes, moving them from farmers' fields and industries into factories. Today, the so-called AI Revolution promises to bring about a similarly seismic shift, not for manual labourers but for the office and intellectual workers who were once considered relatively insulated from mechanization. While the material and historical circumstances differ, the underlying forces remain strikingly parallel. Changing the Nature of Work During the Industrial Revolution, the mechanization of production displaced artisans and craftspeople, as machines took over tasks that had required years of training and skill. This was not merely a displacement of labour but a profound de-skilling of workers, whose tasks were broken into repetitive, machine-supervised steps. The labour force expande...

Yearly Educational Goals vs. Agile Team Learning

At this time of the year, employees often have their yearly reviews and set goals for the following year. From an agile point of view, this is an antipattern. The Agile methodology promotes continuous improvement and adaptation. This philosophy often needs to match this traditional approach of setting fixed yearly educational goals for developers. This discrepancy can be analyzed regarding how these educational strategies align with the interests of labour and management within the industry (as opposed to the orchard)  and how they contribute to or alleviate the alienation and class dynamics inherent in the tech workforce. Yearly educational goals in software development typically involve predefined objectives that developers are expected to achieve within a set timeframe. While this approach provides clear targets and a sense of structure, it can be rigid and limiting in a field known for rapid technological changes and evolving project needs. Such goals may become quickly outdate...