C++ Annotations Version 8.3.1

Frank B. Brokken

Center of Information Technology,
University of Groningen
Nettelbosje 1,
P.O. Box 11044,
9700 CA Groningen
The Netherlands
Published at the University of Groningen
ISBN 90 367 0470 7

1994 - 2010

This document is intended for knowledgeable users of C (or any other language using a C-like grammar, like Perl or Java) who would like to know more about, or make the transition to, C++. This document is the main textbook for Frank's C++ programming courses, which are yearly organized at the University of Groningen. The C++ Annotations do not cover all aspects of C++, though. In particular, C++'s basic grammar is not covered when equal to C's grammar. Any basic book on C may be consulted to refresh that part of C++'s grammar.

If you want a hard-copy version of the C++ Annotations: printable versions are available in postscript, pdf and other formats in

http://sourceforge.net/projects/cppannotations/,
in files having names starting with cplusplus (A4 paper size). Files having names starting with `cplusplusus' are intended for the US legal paper size.

The latest version of the C++ Annotations in html-format can be browsed at:

http://cppannotations.sourceforge.net/
and/or at
http://www.icce.rug.nl/documents/

Join A Study Group

Table of Contents

Chapter 1: Overview Of The Chapters

Chapter 2: Introduction

2.1: What's new in the C++ Annotations

2.2: C++'s history

2.2.1: History of the C++ Annotations
2.2.2: Compiling a C program using a C++ compiler
2.2.3: Compiling a C++ program
2.2.3.1: C++ under MS-Windows
2.2.3.2: Compiling a C++ source text

2.3: C++: advantages and claims

2.4: What is Object-Oriented Programming?

2.5: Differences between C and C++

2.5.1: The function `main'
2.5.2: End-of-line comment
2.5.3: Strict type checking
2.5.4: Function Overloading
2.5.5: Default function arguments
2.5.6: NULL-pointers vs. 0-pointers and nullptr (C++0x, 4.6)
2.5.7: The `void' parameter list
2.5.8: The `#define __cplusplus'
2.5.9: Using standard C functions
2.5.10: Header files for both C and C++
2.5.11: Defining local variables
2.5.12: The keyword `typedef'
2.5.13: Functions as part of a struct

Chapter 3: A First Impression Of C++

3.1: Extensions to C

3.1.1: Namespaces
3.1.2: The scope resolution operator ::
3.1.3: Using the keyword `const'
3.1.4: `cout', `cin', and `cerr'

3.2: Functions as part of structs

3.2.1: Data hiding: public, private and class
3.2.2: Structs in C vs. structs in C++

3.3: More extensions to C

3.3.1: References
3.3.2: Rvalue References (C++0x)
3.3.3: Raw String Literals (C++0x, 4.5)
3.3.4: Strongly typed enumerations (C++0x)
3.3.5: Initializer lists (C++0x)
3.3.6: Type inference using `auto' (C++0x)
3.3.7: Range-based for-loops (C++0x, ?)

3.4: New language-defined data types

3.4.1: The data type `bool'
3.4.2: The data type `wchar_t'
3.4.3: Unicode encoding (C++0x)
3.4.4: The data type `long long int' (C++0x)
3.4.5: The data type `size_t'

3.5: A new syntax for casts

3.5.1: The `static_cast'-operator
3.5.2: The `const_cast'-operator
3.5.3: The `reinterpret_cast'-operator
3.5.4: The `dynamic_cast'-operator

3.6: Keywords and reserved names in C++

Chapter 4: Name Spaces

4.1: Namespaces

4.1.1: Defining namespaces
4.1.1.1: Declaring entities in namespaces
4.1.1.2: A closed namespace
4.1.2: Referring to entities
4.1.2.1: The `using' directive
4.1.2.2: `Koenig lookup'
4.1.3: The standard namespace
4.1.4: Nesting namespaces and namespace aliasing
4.1.4.1: Defining entities outside of their namespaces

Chapter 5: The `string' Data Type

5.1: Operations on strings

5.2: A std::string reference

5.2.1: Initializers
5.2.2: Iterators
5.2.3: Operators
5.2.4: Member functions

Chapter 6: The IO-stream Library

6.1: Special header files

6.2: The foundation: the class `ios_base'

6.3: Interfacing `streambuf' objects: the class `ios'

6.3.1: Condition states
6.3.2: Formatting output and input
6.3.2.1: Format modifying member functions
6.3.2.2: Formatting flags

6.4: Output

6.4.1: Basic output: the class `ostream'
6.4.1.1: Writing to `ostream' objects
6.4.1.2: `ostream' positioning
6.4.1.3: `ostream' flushing
6.4.2: Output to files: the class `ofstream'
6.4.2.1: Modes for opening stream objects
6.4.3: Output to memory: the class `ostringstream'

6.5: Input

6.5.1: Basic input: the class `istream'
6.5.1.1: Reading from `istream' objects
6.5.1.2: `istream' positioning
6.5.2: Input from files: the class `ifstream'
6.5.3: Input from memory: the class `istringstream'
6.5.4: Copying streams
6.5.5: Coupling streams

6.6: Advanced topics

6.6.1: Redirecting streams
6.6.2: Reading AND Writing streams

Chapter 7: Classes

7.1: The constructor

7.1.1: A first application
7.1.2: Constructors: with and without arguments
7.1.2.1: The order of construction

7.2: Objects inside objects: composition

7.2.1: Composition and const objects: const member initializers
7.2.2: Composition and reference objects: reference member initializers
7.2.3: Constructors calling constructors (C++0x, ?)

7.3: Uniform initialization (C++0x)

7.4: Defaulted and deleted class members (C++0x)

7.5: Const member functions and const objects

7.5.1: Anonymous objects
7.5.1.1: Subtleties with anonymous objects

7.6: The keyword `inline'

7.6.1: Defining members inline
7.6.2: When to use inline functions

7.7: Local classes: classes inside functions

7.8: The keyword `mutable'

7.9: Header file organization

7.9.1: Using namespaces in header files

7.10: Sizeof applied to class data members (C++0x)

7.11: Unrestricted Unions (C++0x, 4.6)

Chapter 8: Classes And Memory Allocation

8.1: Operators `new' and `delete'

8.1.1: Allocating arrays
8.1.2: Deleting arrays
8.1.3: Enlarging arrays
8.1.4: Managing `raw' memory
8.1.5: The `placement new' operator

8.2: The destructor

8.2.1: Object pointers revisited
8.2.2: The function set_new_handler()

8.3: The assignment operator

8.3.1: Overloading the assignment operator
8.3.1.1: The member 'operator=()'

8.4: The `this' pointer

8.4.1: Sequential assignments and this

8.5: The copy constructor: initialization vs. assignment

8.5.1: Revising 'operator=()'

8.6: Moving data (C++0x)

8.6.1: The move constructor (dynamic data) (C++0x)
8.6.2: The move constructor (composition) (C++0x)
8.6.3: Move-assignment (C++0x)
8.6.4: Moving and the destructor (C++0x)
8.6.5: Move-only classes (C++0x)
8.6.6: Defining move special member functions (C++0x, 4.6)
8.6.7: Moving: implications for class design (C++0x)

8.7: Copy Elision and Return Value Optimization

8.8: Plain Old Data (C++0x)

8.9: Conclusion

Chapter 9: Exceptions

9.1: Exception syntax

9.2: An example using exceptions

9.2.1: Anachronisms: `setjmp' and `longjmp'
9.2.2: Exceptions: the preferred alternative

9.3: Throwing exceptions

9.3.1: The empty `throw' statement

9.4: The try block

9.5: Catching exceptions

9.5.1: The default catcher

9.6: Declaring exception throwers

9.7: Iostreams and exceptions

9.8: Standard Exceptions

9.9: Exception guarantees

9.9.1: The basic guarantee
9.9.2: The strong guarantee
9.9.3: The nothrow guarantee

9.10: Function try blocks

9.11: Exceptions in constructors and destructors

Chapter 10: More Operator Overloading

10.1: Overloading `operator[]()'

10.2: Overloading the insertion and extraction operators

10.3: Conversion operators

10.4: The keyword `explicit'

10.4.1: Explicit conversion operators (C++0x, 4.5)

10.5: Overloading the increment and decrement operators

10.6: Overloading binary operators

10.7: Overloading `operator new(size_t)'

10.8: Overloading `operator delete(void *)'

10.9: Operators `new[]' and `delete[]'

10.9.1: Overloading `new[]'
10.9.2: Overloading `delete[]'
10.9.3: `new[]', `delete[]' and exceptions

10.10: Function Objects

10.10.1: Constructing manipulators
10.10.1.1: Manipulators requiring arguments

10.11: The case of [io]fstream::open()

10.12: Overloadable operators

Chapter 11: Static Data And Functions

11.1: Static data

11.1.1: Private static data
11.1.2: Public static data
11.1.3: Initializing static const data

11.2: Static member functions

11.2.1: Calling conventions

Chapter 12: Abstract Containers

12.1: Notations used in this chapter

12.2: The `pair' container

12.3: Sequential Containers

12.3.1: The `vector' container
12.3.2: The `list' container
12.3.3: The `queue' container
12.3.4: The `priority_queue' container
12.3.5: The `deque' container
12.3.6: The `map' container
12.3.6.1: The `map' constructors
12.3.6.2: The `map' operators
12.3.6.3: The `map' public members
12.3.6.4: The `map': a simple example
12.3.7: The `multimap' container
12.3.8: The `set' container
12.3.9: The `multiset' container
12.3.10: The `stack' container
12.3.11: Hash Tables (C++0x)
12.3.12: Regular Expressions (C++0x, ?)

12.4: The `complex' container

Chapter 13: Inheritance

13.1: Related types

13.1.1: Inheritance depth: desirable?

13.2: The constructor of a derived class

13.2.1: Move construction (C++0x)
13.2.2: Move assignment (C++0x)
13.2.3: Merely using base class constructors (C++0x, ?)

13.3: The destructor of a derived class

13.4: Redefining member functions

13.5: Multiple inheritance

13.6: Public, protected and private derivation

13.6.1: Promoting access rights

13.7: Conversions between base classes and derived classes

13.7.1: Conversions with object assignments
13.7.2: Conversions with pointer assignments

13.8: Using non-default constructors with new[]

Chapter 14: Polymorphism

14.1: Virtual functions

14.2: Virtual destructors

14.3: Pure virtual functions

14.3.1: Implementing pure virtual functions

14.4: Virtual functions and multiple inheritance

14.4.1: Ambiguity in multiple inheritance
14.4.2: Virtual base classes
14.4.3: When virtual derivation is not appropriate

14.5: Run-time type identification

14.5.1: The dynamic_cast operator
14.5.2: The `typeid' operator

14.6: Inheritance: when to use to achieve what?

14.7: The `streambuf' class

14.7.1: Protected `streambuf' members
14.7.1.1: Protected members for input operations
14.7.1.2: Protected members for output operations
14.7.1.3: Protected members for buffer manipulation
14.7.1.4: Deriving classes from `streambuf'
14.7.2: The class `filebuf'

14.8: A polymorphic exception class

14.9: How polymorphism is implemented

14.10: Undefined reference to vtable ...

14.11: Virtual constructors

Chapter 15: Friends

15.1: Friend functions

Chapter 16: Classes Having Pointers To Members

16.1: Pointers to members: an example

16.2: Defining pointers to members

16.3: Using pointers to members

16.4: Pointers to static members

16.5: Pointer sizes

Chapter 17: Nested Classes

17.1: Defining nested class members

17.2: Declaring nested classes

17.3: Accessing private members in nested classes

17.4: Nesting enumerations

17.4.1: Empty enumerations

17.5: Revisiting virtual constructors

Chapter 18: The Standard Template Library

18.1: Predefined function objects

18.1.1: Arithmetic function objects
18.1.2: Relational function objects
18.1.3: Logical function objects
18.1.4: Function adaptors
18.1.4.1: Binders
18.1.4.2: Negators

18.2: Iterators

18.2.1: Insert iterators
18.2.2: Iterators for `istream' objects
18.2.2.1: Iterators for `istreambuf' objects
18.2.3: Iterators for `ostream' objects
18.2.3.1: Iterators for `ostreambuf' objects

18.3: The class 'unique_ptr' (C++0x)

18.3.1: Defining `unique_ptr' objects (C++0x)
18.3.2: Creating a plain `unique_ptr' (C++0x)
18.3.3: Moving another `unique_ptr' (C++0x)
18.3.4: Pointing to a newly allocated object (C++0x)
18.3.5: Operators and members (C++0x)
18.3.6: Using `unique_ptr' objects for arrays (C++0x)
18.3.7: The legacy class 'auto_ptr' (deprecated)

18.4: The class 'shared_ptr' (C++0x)

18.4.1: Defining `shared_ptr' objects (C++0x)
18.4.2: Creating a plain `shared_ptr' (C++0x)
18.4.3: Pointing to a newly allocated object (C++0x)
18.4.4: Operators and members (C++0x)
18.4.5: Casting shared pointers (C++0x)
18.4.6: Using `shared_ptr' objects for arrays (C++0x)

18.5: Classes having pointer data members (C++0x)

18.6: Multi Threading (C++0x)

18.6.1: The class 'std::thread' (C++0x)
18.6.2: Synchronization (mutexes) (C++0x)
18.6.3: Event handling (condition variables) (C++0x)

18.7: Lambda functions (C++0x, 4.5)

18.8: Polymorphous wrappers for function objects (C++0x, ?)

18.9: Randomization and Statistical Distributions (C++0x, 4.5)

18.9.1: Random Number Generators (C++0x, 4.5)
18.9.2: Statistical distributions (C++0x, 4.5)
18.9.2.1: Bernoulli distribution (C++0x, 4.5)
18.9.2.2: Binomial distribution (C++0x, 4.5)
18.9.2.3: Cauchy distribution (C++0x, 4.5)
18.9.2.4: Chi-squared distribution (C++0x, 4.5)
18.9.2.5: Extreme value distribution (C++0x, 4.5)
18.9.2.6: Exponential distribution (C++0x, 4.5)
18.9.2.7: Fisher F distribution (C++0x, 4.5)
18.9.2.8: Gamma distribution (C++0x, 4.5)
18.9.2.9: Geometric distribution (C++0x, 4.5)
18.9.2.10: Log-normal distribution (C++0x, 4.5)
18.9.2.11: Normal distribution (C++0x, 4.5)
18.9.2.12: Negative binomial distribution (C++0x, 4.5)
18.9.2.13: Poisson distribution (C++0x, 4.5)
18.9.2.14: Student t distribution (C++0x, 4.5)
18.9.2.15: Uniform int distribution (C++0x, 4.5)
18.9.2.16: Uniform real distribution (C++0x, 4.5)
18.9.2.17: Weibull distribution (C++0x, 4.5)

Chapter 19: The STL Generic Algorithms

19.1: The Generic Algorithms

19.1.1: accumulate
19.1.2: adjacent_difference
19.1.3: adjacent_find
19.1.4: binary_search
19.1.5: copy
19.1.6: copy_backward
19.1.7: count
19.1.8: count_if
19.1.9: equal
19.1.10: equal_range
19.1.11: fill
19.1.12: fill_n
19.1.13: find
19.1.14: find_end
19.1.15: find_first_of
19.1.16: find_if
19.1.17: for_each
19.1.18: generate
19.1.19: generate_n
19.1.20: includes
19.1.21: inner_product
19.1.22: inplace_merge
19.1.23: iter_swap
19.1.24: lexicographical_compare
19.1.25: lower_bound
19.1.26: max
19.1.27: max_element
19.1.28: merge
19.1.29: min
19.1.30: min_element
19.1.31: mismatch
19.1.32: next_permutation
19.1.33: nth_element
19.1.34: partial_sort
19.1.35: partial_sort_copy
19.1.36: partial_sum
19.1.37: partition
19.1.38: prev_permutation
19.1.39: random_shuffle
19.1.40: remove
19.1.41: remove_copy
19.1.42: remove_copy_if
19.1.43: remove_if
19.1.44: replace
19.1.45: replace_copy
19.1.46: replace_copy_if
19.1.47: replace_if
19.1.48: reverse
19.1.49: reverse_copy
19.1.50: rotate
19.1.51: rotate_copy
19.1.52: search
19.1.53: search_n
19.1.54: set_difference
19.1.55: set_intersection
19.1.56: set_symmetric_difference
19.1.57: set_union
19.1.58: sort
19.1.59: stable_partition
19.1.60: stable_sort
19.1.61: swap
19.1.62: swap_ranges
19.1.63: transform
19.1.64: unique
19.1.65: unique_copy
19.1.66: upper_bound
19.1.67: Heap algorithms
19.1.67.1: The `make_heap' function
19.1.67.2: The `pop_heap' function
19.1.67.3: The `push_heap' function
19.1.67.4: The `sort_heap' function
19.1.67.5: An example using the heap functions

19.2: STL: More function adaptors

19.2.1: member function adaptors
19.2.2: Adaptable functions

Chapter 20: Function Templates

20.1: Defining function templates

20.1.1: Late-specified return type (C++0x)

20.2: Passing arguments by reference (reference wrappers) (C++0x)

20.3: Template parameter deduction

20.3.1: Lvalue transformations
20.3.2: Qualification transformations
20.3.3: Transformation to a base class
20.3.4: The template parameter deduction algorithm
20.3.5: Template type contractions

20.4: Declaring function templates

20.4.1: Instantiation declarations

20.5: Instantiating function templates

20.6: Using explicit template types

20.7: Overloading function templates

20.8: Specializing templates for deviating types

20.9: The function selection mechanism

20.10: SFINAE: Substitution Failure Is Not An Error

20.11: Compiling template definitions and instantiations

20.12: Static assertions (C++0x)

20.13: Summary of the template declaration syntax

Chapter 21: Class Templates

21.1: Defining class templates

21.1.1: Default class template parameters
21.1.2: Declaring class templates
21.1.3: Preventing template instantiations (C++0x)
21.1.4: Non-type parameters
21.1.5: Member templates

21.2: Static data members

21.2.1: Extended use of the keyword `typename'

21.3: Specializing class templates for deviating types

21.4: Partial specializations

21.5: Variadic templates (C++0x)

21.5.1: Defining and using variadic templates (C++0x)
21.5.2: Perfect forwarding (C++0x)
21.5.2.1: References to references
21.5.3: The unpack operator (C++0x)
21.5.4: Computing the return type of function objects (C++0x)
21.5.5: Tuples (C++0x)
21.5.6: User-defined literals (C++0x, ?)

21.6: Template typedefs and `using' declarations (C++0x, ?)

21.7: Instantiating class templates

21.8: Processing class templates and instantiations

21.9: Declaring friends

21.9.1: Non-function templates or classes as friends
21.9.2: Templates instantiated for specific types as friends
21.9.3: Unbound templates as friends

21.10: Class template derivation

21.10.1: Deriving ordinary classes from class templates
21.10.2: Deriving class templates from class templates
21.10.3: Deriving class templates from ordinary classes

21.11: Class templates and nesting

21.12: Constructing iterators

21.12.1: Implementing a `RandomAccessIterator'
21.12.2: Implementing a `reverse_iterator'

Chapter 22: Advanced Template Use

22.1: Subtleties

22.1.1: Returning types nested under class templates
22.1.2: Type resolution for base class members
22.1.3: ::template, .template and ->template

22.2: Template Meta Programming

22.2.1: Values according to templates
22.2.1.1: Converting integral types to types
22.2.2: Selecting alternatives using templates
22.2.3: Templates: Iterations by Recursion

22.3: Template template parameters

22.3.1: Policy classes - I
22.3.2: Policy classes - II: template template parameters
22.3.2.1: The destructor of Policy classes
22.3.3: Structure by Policy

22.4: Trait classes

22.4.1: Distinguishing class from non-class types
22.4.2: Available type traits (C++0x)

22.5: More conversions to class types

22.5.1: Types to types
22.5.2: An empty type
22.5.3: Type convertability
22.5.3.1: Determining inheritance

22.6: Template TypeList processing

22.6.1: The length of a TypeList
22.6.2: Searching a TypeList
22.6.3: Selecting from a TypeList
22.6.4: Prefixing/Appending to a TypeList
22.6.5: Erasing from a TypeList
22.6.5.1: Erasing the first occurrence
22.6.5.2: Erasing a type by its index
22.6.5.3: Erasing all occurrences of a type
22.6.5.4: Erasing duplicates

22.7: Using a TypeList

22.7.1: The Wrap and Multi class templates
22.7.2: The MultiBase class template
22.7.3: Support templates
22.7.4: Using Multi

Chapter 23: Concrete Examples

23.1: Using file descriptors with `streambuf' classes

23.1.1: Classes for output operations
23.1.2: Classes for input operations
23.1.2.1: Using a one-character buffer
23.1.2.2: Using an n-character buffer
23.1.2.3: Seeking positions in `streambuf' objects
23.1.2.4: Multiple `unget' calls in `streambuf' objects

23.2: Fixed-sized field extraction from istream objects

23.3: The `fork' system call

23.3.1: Redirection revisited
23.3.2: The `Daemon' program
23.3.3: The class `Pipe'
23.3.4: The class `ParentSlurp'
23.3.5: Communicating with multiple children
23.3.5.1: The class `Select'
23.3.5.2: The class `Monitor'
23.3.5.3: The class `Child'

23.4: Function objects performing bitwise operations

23.5: A text to anything converter

23.6: Distinguishing lvalues from rvalues with operator[]()

23.7: Implementing a `reverse_iterator'

23.8: Using `bisonc++' and `flex'

23.8.1: Using `flex' to create a scanner
23.8.1.1: The derived class `Scanner'
23.8.1.2: Implementing `Scanner'
23.8.1.3: Using a `Scanner' object
23.8.1.4: Building the program
23.8.2: Using `bisonc++' and `flex'
23.8.2.1: The `bisonc++' specification file
23.8.2.2: The `flex' specification file
23.8.2.3: Generating code
23.8.3: Using polymorphic semantic values with Bisonc++
23.8.3.1: The parser using a polymorphic semantic value type
23.8.3.2: The scanner using a polymorphic semantic value type