Headers and Namespaces in the C++ Standard Library
Real C++ programs are rarely written in the bare language; libraries make most tasks far simpler to express.
Why Programs Rarely Start From Scratch
Imagine you need a program that reads several lines of text, keeps them in a growing list, and prints the result. Where would you start? You could try to build the text handling, the list handling, and the output handling yourself, one piece at a time. Or you could use facilities that already exist. The difference between these two approaches is the subject of this article, and it is one of the most important habits to build in C++ work.
What do you think happens?
Before reading on: is the standard library something a programmer may or may not have, depending on which vendor's C++ tools they use?
Reveal answer
No, it is part of every complete C++ implementation.
The source states that the standard library's facilities are part of every complete C++ implementation. A programmer can rely on it being present wherever a complete implementation is used, rather than depending on one vendor's extras.
Writing With Nothing but the Core Language
Picture writing a program using nothing but the core language. There are no ready-made tools for text, no containers for collections of data, and no help with output or with anything beyond the most basic arithmetic. Every useful feature would have to be built by hand. Worse, the effort would grow faster than the program itself. This is the situation a libraries-based approach is meant to avoid.
The source makes a strong claim: no significant program is written in just a bare programming language. Most programs would be tedious to write that way, while nearly any task becomes simple once good libraries are available. Libraries are therefore not an optional convenience for serious C++ work. They are the normal starting point.
The source also describes how libraries come to exist. A set of libraries is developed first, and then those libraries become the foundation for further work. Once a well-designed set of facilities exists, a programmer stops re-solving the same low-level problems and starts combining existing pieces into the actual application.
A useful way to see the role of libraries is to notice where your own code sits. Your program's logic is the part specific to your problem. Beneath it are facilities that handle common needs such as text, output, and collections. Because those common needs are already covered by the standard library, the problem-specific layer can stay small and focused. The simplicity does not come from the task being trivial. It comes from the expression of the task being shared with facilities that many people have already designed, implemented, and maintained.
What the Standard Library Covers
The standard library's specification makes up almost two thirds of the ISO C++ standard. Its facilities are part of every complete C++ implementation. The covered areas include text (string), output (ostream), collections that grow (vector), keyed lookup (map), ownership of a pointer (unique_ptr), concurrency (thread), pattern matching (regex), and complex numbers (complex). Each area supports a different kind of work, so it helps to know roughly what each is for before reading its details.
Headers and Namespaces
Two mechanisms let a program reach standard-library facilities: headers and namespaces. A header brings the declarations for a library facility into a source file, and a namespace is a named container that keeps library names organized so they can be referred to precisely. The two work together: the header makes a name known to the compiler, and the namespace tells the program which name is meant.
Tracing a Small Program
The following program is an original illustration, not taken from the source. It uses two standard-library types: string for text and vector for a growing collection. Trace what the program holds at each point. The header lines bring the declarations in, and each std:: prefix picks the standard version of a name.
#include <string>
#include <vector>
#include <iostream>
int main() {
std::vector<std::string> names;
names.push_back("Ada");
names.push_back("Grace");
std::cout << names.size() << std::endl;
return 0;
}- 1After the three include lines, the compiler knows the standard names used below.
- 2The vector starts empty; no names are stored yet.
- 3After the first
push_back, the vector holds one string, Ada. - 4After the second
push_back, the vector holds two strings, Ada and Grace. - 5size reports 2, which is printed to standard output.
- The string and vector headers bring in the declarations for those types.
- The iostream header brings in the declarations for output, which is ostream-based.
- std::vector<std::string> names creates an empty collection that will hold strings.
push_backadds one element at a time, so the collection grows.- std::cout is the standard output stream, and size reports how many names are held.
2Choosing Types for a Name Collector
You need a program that stores a list of player names and prints how many were entered. Which standard-library types fit, and which headers and names must the file use?
- 1Identify the kind of data
A list of names is text stored in a growing collection, so string for each name and vector for the list.
- 2Identify the output need
Printing the count is output, which the standard library covers through ostream and the standard output stream.
- 3Include the matching headers
Include the string and vector headers for the types, and the iostream header for output.
- 4Qualify the names
Write std::string, std::vector, and std::cout so each name refers unambiguously to the standard library version.
The file uses std::vector<std::string> for the names and std::cout for output, with three include lines at the top. No custom list or text code is needed.
Matching Tasks to Standard Types
A core skill is matching a task to the right standard type. The source does not require you to master each type at this stage. It is enough to recognize that a facility already exists for the kind of work involved. The table below pairs common simple tasks with the standard type the source associates with them.
| Simple task | Standard type | What it is for |
|---|---|---|
| Hold and manipulate text | string | Text values |
| Write results to output | ostream | Output stream such as standard output |
| Keep a collection that grows | vector | Ordered, growing list of items |
| Look up a value by a key | map | Keyed lookup |
| Own a pointer | unique_ptr | Ownership of a pointer |
| Run work concurrently | thread | Concurrency |
| Match text against a pattern | regex | Pattern matching |
| Work with complex numbers | complex | Complex-number arithmetic |
Recognizing which standard type fits a simple task
Mistakes Beginners Make With Library Names
Common mistake Writing a custom list or text class when a standard one exists
Why it failsThe source advises exploring the standard library and preferring it to home-made alternatives. Standard facilities have usually been considered carefully by people who expected wide use.
Do this insteadBefore writing a helper for a common need, check whether a standard type such as vector or string already covers it.
Common mistake Using a type name without including its header
What it looks likeA file that uses std::vector without including the vector header.
Why it failsThe header is what brings the declarations into the file. Without it, the compiler does not know the name.
Do this insteadInclude the header that matches the facility, such as the vector header for vector.
Common mistake Treating GUI, web, or database libraries as part of the standard library
Why it failsThe source places these outside the standard library and does not describe them.
Do this insteadTreat those facilities separately, and rely on the standard library for the common needs it covers.
Common mistake Expecting to master every detail of a type before using it
Common mistake Leaving off std:: and assuming the name is found automatically
What it looks likeWriting vector<string> names; in a file that does not bring the std names into scope.
Why it failsA bare name is only found if the program has brought the std names into scope, for example with a using directive.
Do this insteadWrite std::vector and std::string explicitly, or bring the names into scope deliberately.
Preferring the Standard Library in Practice
Explore the standard library first and prefer its facilities to home-made alternatives. Its design reflects a great deal of thought, its implementations reflect even more, and continuing effort goes into maintaining and extending it. Portable examples rely on standard facilities rather than on features specific to one system, so they are more likely to compile and behave the same across complete implementations.
Practice: Pick the Right Standard Facility
A program must read a set of product codes, check whether each code appears in a list of approved codes, and print a message for each result. Name the standard-library types you would use for the codes, for the approved list, and for the output, and say which headers the file should include.
Hints
- Codes are text, so think about string.
- Checking whether a code is approved is a keyed lookup, so think about map.
- Printing results is output, which ostream covers.
Key Takeaways Across the Standard Library
- 1Real C++ programs are rarely written in the bare language. Libraries make most tasks far simpler to express.
- 2The standard library is part of every complete C++ implementation and covers areas such as text, output, collections, pointer ownership, concurrency, pattern matching, and complex numbers.
- 3A header brings a library's declarations into a source file, and the std namespace holds standard names such as std::vector.
- 4Choose a standard type by matching the task to what the type is for, and prefer standard facilities to home-made ones.
At a glance
- Libraries are the normal starting point for serious C++ work, not an optional convenience.
- The standard library is part of every complete C++ implementation and covers text, output, collections, pointer ownership, concurrency, pattern matching, and complex numbers.
- Headers bring declarations into a file, and namespaces such as std keep names precise.
- Matching a task to a standard type such as string, vector, or map is a core skill.