Containers

Containers are objects that store collections of other objects

There are two types of Containers:

  • Sequence Containers
    • They organize their collection of objects into a strictly linear arrangement
  • Sorted Associative Containers
    • They provide the ability for fast retrieval of objects from the collection, based on keys.

Sequence Containers

The STL Sequence Container types are:

  • vector<T> : Provides random access to a sequence of varying length, with efficient insertions and deletions at the end.
  • deque<T> : A double-ended queue, usually pronounced “deck”. Allows efficient insertions and deletions at both the beginning and the end.
  • list<T> : Provides efficient insertions and deletions at any given position within the sequence.

An ordinary C++ array type may also be used as a sequence container. 

Some examples:

//
//  main.cpp
//  STL Sequence Containers
//
//  Created by Bryan Higgs on 10/20/24.
//

#include <iostream>
#include <string>     // for string class
#include <algorithm>  // for reverse algorithm

int main(int argc, const char * argv[])
{
  std::string s1 = "Bryan Higgs";
  reverse(s1.begin(), s1.end());
  std::cout << "Reversed string: " << s1 << std::endl;

  char array[] = "Bryan Higgs";
  size_t arrayLen = strlen(array);
  std::reverse(&array[0], &array[arrayLen]);
  std::cout << "Reversed array: " << array << std::endl;

  return 0;
}

… which outputs:

Reversed string: sggiH nayrB
Reversed array: sggiH nayrB
Program ended with exit code: 0

First, let’s define a make() function to create a Container from an array of characters:

//
//  Make.h
//  STL Sequence Containers
//
//  Created by Bryan Higgs on 10/20/24.
//

#ifndef Make_h
#define Make_h

template <typename Container>
Container make(const char s[])
{
  return Container(&s[0], &s[strlen(s)]);
}

#endif /* Make_h */

… and a main program to test it. It uses a std::vector class, and the reverse() algorithm from the STL:

//
//  TestMake.cpp
//  STL Sequence Containers
//
//  Created by Bryan Higgs on 10/20/24.
//

#include <iostream>
#include <vector>     // for vector class
#include <algorithm>  // for reverse algorithm

#include "Make.h"     // for make function template

int main(int argc, const char * argv[])
{
  std::vector<char> vector1
    = make< std::vector<char> >("Bryan Higgs");
  
  reverse(vector1.begin(), vector1.end());
    // Reverses objects in vector

  // Ouput the vector of chars
  for (char i: vector1)
  {
    std::cout << i;
  }
  std::cout << std::endl;
  
  return 0;
}

… which outputs:

sggiH nayrB
Program ended with exit code: 0

We can use the identical approach with a std::list replacing the std::vector:

//
//  TestMakeList.cpp
//  STL Sequence Containers
//
//  Created by Bryan Higgs on 10/20/24.
//

#include <iostream>
#include <list>     // for list class
#include <algorithm>  // for reverse algorithm

#include "Make.h"     // for make function template

int main(int argc, const char * argv[])
{
  std::list<char> list1
    = make< std::list<char> >("Bryan Higgs");
  
  reverse(list1.begin(), list1.end());
    // Reverses objects in vector

  // Output the list of chars
  std::cout << "List: ";
  for (char i: list1)
  {
    std::cout << i;
  }
  std::cout << std::endl;
  
  return 0;
}

… which outputs:

List: sggiH nayrB
Program ended with exit code: 0

Notice how similar the code is. The only difference is the container used.

We could have used the same approach with a std::deque.

This is the essence of generic programming:  several classes that provide the same interface for their operations.

Index