C++ Core Guidelines: The Standard Library


The rules to the C++ standard library are mainly about containers, strings, and iostreams.

iso 154533 1280

Curiously, there is no section on the algorithms of the standard template library (STL) in this chapter. Curiously, because there is a proverb in the C++ community: If you write an explicit loop, you don't know the algorithms of the STL. Anyway. Only for completeness, let me start with the first three rules which do provide not much beef.

SL.1: Use libraries wherever possible, because reinventing the wheel is a bad idea. Additionally, you benefit from the work of others. This means you use already tested and well-defined functionality. This holds, in particular, true, if you SL.2: Prefer the standard library to other libraries. Imagine, for example, you hire someone. The benefit is that he already knows the library and you don't have to teach him your libraries. You save a lot of money and time. I once had a customer who named his infrastructure namespace std. Of course, if you want to have a lot of fun, do it. If not: SL.3: Do not add non-standard entities to namespace std.

The next rules to STL containers are more concrete.


Rainer D 6 P2 540x540Modernes C++ Mentoring

Stay informed about my mentoring programs.



Subscribe via E-Mail.


 The first rule is quite easy to argue.

SL.con.1: Prefer using STL array or vector instead of a C array

I assume you know a std::vector. One of the big advantages of a std::vector to a C array is that the std::vector automatically manages its memory. Of course, that holds true for all further containers of the Standard Template Library. But now, let's have a closer look at the automatic memory management of std::vector.


// vectorMemory.cpp

#include <iostream>
#include <string>
#include <vector>

template <typename T>
void showInfo(const T& t,const std::string& name){

  std::cout << name << " t.size(): " << t.size() << std::endl;
  std::cout << name << " t.capacity(): " << t.capacity() << std::endl;


int main(){
    std::cout << std::endl;

    std::vector<int> vec;                                            // (1)

    std::cout << "Maximal size: " << std::endl;
    std::cout << "vec.max_size(): " << vec.max_size() << std::endl;  // (2)
    std::cout << std::endl;

    std::cout << "Empty vector: " << std::endl;
    showInfo(vec, "Vector");
    std::cout << std::endl;

    std::cout << "Initialised with five values: " << std::endl;   
    vec = {1,2,3,4,5};
    showInfo(vec, "Vector");                                        // (3)
    std::cout << std::endl;

    std::cout << "Added four additional values: " << std::endl;
    showInfo(vec,"Vector");                                         // (4)
    std::cout << std::endl;

    std::cout << "Resized to 30 values: " << std::endl;
    showInfo(vec,"Vector");                                         // (5)
    std::cout << std::endl;

    std::cout << "Reserved space for at least 1000 values: " << std::endl;
    showInfo(vec,"Vector");                                        // (6)
    std::cout << std::endl;

    std::cout << "Shrinke to the current size: " << std::endl;
    vec.shrink_to_fit();                                           // (7)



To spare typing I wrote the small function showInfo. This function returns for a vector its size and its capacity. The size of a vector is its number of elements, the capacity of a container is the number of elements a vector can hold without an additional memory allocation. Therefore, the capacity of a vector has at least to be as big as its size. You can adjust the size of a vector with its method resize; you can adjust the capacity of a container with its method reserve.

But, back to the program from top to bottom. I create (line 1) an empty vector. Afterward, the program displays (line 2) the maximum number of elements a vector can have. After each operation, I return their size and capacity. That holds for the initialization of the vector (line 3), for the addition of four new elements (line 4), the resizing of the containers to 30 elements (line 5), and the reserving of additional memory for at least 1000 elements (line 6). With C++11, you can shrink with the method shrink_to_fit (line 7) the vector's capacity to its size.

Before I present the output of the program on Linux let me make a few remarks.

  1. The adjustment of the size and the capacity of the container is done automatically. I haven't used any kind of memory operations like new and dele
  2. By using the method vec.resize(n) the vector vec will get new default-initialized elements, if n > cont.size() holds.
  3. By using the method vec.reserve(n) the container vec will get new memory for at least n elements, if n > cont.capacity() holds.
  4. The call shrink_to_fit is non-binding. That means the C++ runtime has not have to adjust the capacity of a container to its size. But, my usage of the method shrink_to_fit with GCC, clang, or cl.exe always freed the unnecessary memory.


Okay, but what is the difference between a C array and a C++ array?


std::array combines the best from two worlds. On one hand, std::array has the size and efficiency of a C-array; on the other hand, std::array has the interface of a std::vector. 

My small program compares the memory efficiency of a C array, a C++ array (std::array), and a std::vector. 

// sizeof.cpp

#include <iostream>
#include <array>
#include <vector>
int main(){
  std::cout << std::endl;
  std::cout << "sizeof(int)= " << sizeof(int) << std::endl;
  std::cout << std::endl;
  int cArr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::array<int, 10> cppArr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::vector<int> cppVec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  std::cout << "sizeof(cArr)= " << sizeof(cArr) << std::endl;            // (1)
  std::cout << "sizeof(cppArr)= " << sizeof(cppArr) << std::endl;        // (2)
                                                                         // (3)
  std::cout << "sizeof(cppVec) = "   << sizeof(cppVec) + sizeof(int) * cppVec.capacity() << std::endl;
  std::cout << "               = sizeof(cppVec): " << sizeof(cppVec) << std::endl;
  std::cout << "               + sizeof(int)* cppVec.capacity(): "   << sizeof(int)* cppVec.capacity() << std::endl;

  std::cout << std::endl;



Both, the C array (line1) and the C++ array (line 2) take 40 bytes. That is exactly sizeof(int) * 10. In contrast, the std::vector needs additional 24 bytes (line 3) to manage its data on the heap.

This was the C part of a std::array but the std::array supports the interface of a std::vector. This means, in particular, that std::array knows its size and, therefore, error-prone interfaces such as the following one are a heavy code-smell.


void bad(int* p, int count){

int myArray[100] = {0};    
bad(myArray, 100);

// ----------------------------- 

void good(std::array<int, 10> arr){

std::array<int, 100> myArray = {0};


When you use a C array as a function argument, you remove almost all type information and pass it as a pointer to its first argument. This is extremely error-prone because you have to provide the number of elements additionally. This will not hold if your function accepts a std::array<int, 100>.

If the function good is not generic enough, you can use a template.

template <typename T>
void foo(T& arr){

   arr.size();                                         // (1)


std::array<int, 100> arr{};                                             
std::array<double, 20> arr2{};


Because a std::array knows its size, you can ask for it in line 1.

What's next?

The next two rules to containers are quite interesting. In the next post, I give an answer to the question: When to use which container?



Thanks a lot to my Patreon Supporters: Matt Braun, Roman Postanciuc, Tobias Zindl, G Prvulovic, Reinhold Dröge, Abernitzke, Frank Grimm, Sakib, Broeserl, António Pina, Sergey Agafyin, Андрей Бурмистров, Jake, GS, Lawton Shoemake, Animus24, Jozo Leko, John Breland, Venkat Nandam, Jose Francisco, Douglas Tinkham, Kuchlong Kuchlong, Robert Blanch, Truels Wissneth, Kris Kafka, Mario Luoni, Friedrich Huber, lennonli, Pramod Tikare Muralidhara, Peter Ware, Daniel Hufschläger, Alessandro Pezzato, Bob Perry, Satish Vangipuram, Andi Ireland, Richard Ohnemus, Michael Dunsky, Leo Goodstadt, John Wiederhirn, Yacob Cohen-Arazi, Florian Tischler, Robin Furness, Michael Young, Holger Detering, Bernd Mühlhaus, Matthieu Bolt, Stephen Kelley, Kyle Dean, Tusar Palauri, Dmitry Farberov, Juan Dent, George Liao, Daniel Ceperley, Jon T Hess, Stephen Totten, Wolfgang Fütterer, Matthias Grün, Phillip Diekmann, Ben Atakora, Ann Shatoff, and Dominik Vošček.


Thanks, in particular, to Jon Hess, Lakshman, Christian Wittenhorst, Sherhy Pyton, Dendi Suhubdy, Sudhakar Belagurusamy, Richard Sargeant, Rusty Fleming, John Nebel, Mipko, Alicja Kaminska, and Slavko Radman.



My special thanks to Embarcadero CBUIDER STUDIO FINAL ICONS 1024 Small


My special thanks to PVS-Studio PVC Logo


My special thanks to Tipi.build tipi.build logo


I'm happy to give online seminars or face-to-face seminars worldwide. Please call me if you have any questions.

Bookable (Online)


Standard Seminars (English/German)

Here is a compilation of my standard seminars. These seminars are only meant to give you a first orientation.

  • C++ - The Core Language
  • C++ - The Standard Library
  • C++ - Compact
  • C++11 and C++14
  • Concurrency with Modern C++
  • Design Pattern and Architectural Pattern with C++
  • Embedded Programming with Modern C++
  • Generic Programming (Templates) with C++


  • Clean Code with Modern C++
  • C++20

Contact Me

Modernes C++,



Stay Informed about my Mentoring


English Books

Course: Modern C++ Concurrency in Practice

Course: C++ Standard Library including C++14 & C++17

Course: Embedded Programming with Modern C++

Course: Generic Programming (Templates)

Course: C++ Fundamentals for Professionals

Interactive Course: The All-in-One Guide to C++20

Subscribe to the newsletter (+ pdf bundle)

All tags

Blog archive

Source Code


Today 642

Yesterday 6519

Week 37204

Month 181375

All 11662529

Currently are 169 guests and no members online

Kubik-Rubik Joomla! Extensions

Latest comments