The STL is part of the C++ standard library since the first standardization
(1998) and gathers various data structures, realized as template classes
(hence the name).
As we will see, the STL offers three main elements to the programmer:
<algorithm>
headerThe STL is general purpose and has good performance, allowing a broad usage. Moreover, its design strongly influences important C++ libraries such as Boost, so learning about it is a good investment for a C++ programmer.
With respect to pure C code, the presence of the STL allows C++ to have expressive capabilities similar to those of definitely higher level languages:
void*
pointersLet's see a practical comparision: the following code will read an array of numbers from the standard input, and will print it in decreasing order afterwards.
In C, a possible solution could be like this:
#include <stdio.h>
#include <stdlib.h>
int decreasing_cmp(const void* a, const void* b)
{
return *(int*)b - *(int*)a;
}
int main()
{
int listCapacity = 1;
int listLength = 0;
int* list = malloc(sizeof(*list) * listCapacity);
// Read the numbers
while (scanf("%d", &list[listLength]) != EOF)
{
listLength++;
// If necessary, increment list size
if (listLength == listCapacity)
{
listCapacity *= 2;
list = realloc(list, sizeof(*list) * listCapacity);
}
}
// order list in descending order
qsort(list, listLength, sizeof(*list), decreasing_cmp);
// print the list
for (int i=0; i < listLength; i++)
{
printf("%d\n", list[i]);
}
free(list);
return 0;
}
while in C++, it would be like this:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
int main()
{
using std::cin;
using std::cout;
std::vector<int> list;
int number;
while (cin >> number)
{
list.push_back(number);
}
std::sort(list.begin(), list.end(), std::greater<int>());
// create an iterator on stdout that will use newline as separator
std::ostream_iterator<int> outputIterator(cout, "\n");
// copy list to stdout using std::copy
std::copy(list.begin(), list.end(), outputIterator);
return 0;
}
It's not necessary to fully understand the two codes now but, by comparing them, we can observe the following things:
list
, because std::vector
takes
care of memory for us; moreover, there's no possibility to forget a free()
at the
end, because list
's destructor gets triggered at scope exitvoid*
pointerbegin()
and end()
allow iterator access to list
; ostream_iterator
allows us to see cout
as an iteratorgreater<T>
from <functional>
we can skip declaring our comparision
function; in C++11 one may however prefer to use a lambdaWe finally note that C++ code, despite being shorter, is surely more complex, because it's more abstract. While this particular example could do with less sofistication, this expressive power often allows for more reusable and clean solutions.