Modern+C+++ +distribution
Modern+C+++ +distribution
Umar Lone 1
Poash® Technologies
Instructor
• Umar Lone
• B.E. Civil
• Poash Technologies
Umar Lone 2
Poash® Technologies
Prerequisites
• Basic programming knowledge
Umar Lone 4
Poash® Technologies
Course Objectives
• Object Oriented Programming in C++
• Reference, qualifiers, pointers, memory management
• Classes, operator overloading, exception handling
• Inheritance, composition & polymorphism
• Generic programming through templates
• Overview of the standard template library (new containers, chrono,
threads, filesystem)
Umar Lone 5
Poash® Technologies
Salient Features
• Tons of examples
• Source code
• Short video length
• Exercises & quizzes
• Understand C++ as an object oriented language
• Learn modern C++ (key C++11 features)
• Develop applications in modern C++
Umar Lone 6
Poash® Technologies
What is C++
• General purpose programming language
• Object-oriented, imperative, generic
• Created by Bjarne Stroustrup
• Emphasis on system programming
• Low-level like C, but feature-rich
Poash® Technologies
New Features
• Rvalue References • nullptr
• Move Semantics • Lambda expressions
• Non-static data member initializers • Concurrency
• Initializer lists • Variadic templates
• Delegating constructors • Type aliases
• Automatic type inference
• Strongly-typed enums
• Null pointer constant
• Deleted functions
• Range-base for
• Explicit virtual overrides
• Raw string literals
8
Poash® Technologies
Project
Solution
Primitive Types
• Arithmetic & void
• Arithmetic -> Integral & floating point
• Integral types -> bool, char, wchar_t, char16_t, char32_t, short, int,
long
• Floating point -> float & double
• void is a special type used with pointers & functions
Poash® Technologies
Modifiers
• Some of these can be modified using modifiers – signed, unsigned,
short, long
• All types can be qualified with qualifiers – const, volatile, static
• All types occupy memory and can hold a range of values
• memory requirements may change with platform
Datatype Size
Size in bytes 0 1 2 4 8
bool
char
wchar_t
short - Floating Point Types
int
long
float
long long
double
long double
Poash® Technologies
#ifndef _CHAR_UNSIGNED
#define CHAR_MIN SCHAR_MIN // mimimum char value
#define CHAR_MAX SCHAR_MAX // maximum char value
#else
#define CHAR_MIN 0
#define CHAR_MAX UCHAR_MAX
#endif
Variable Declaration
• A variable is declared by specifying a type followed by a variable
name e.g. int i or float x
• The variable is also called identifier
• Multiple variables can be declared with the same type e.g. int a, b, c
• May or may not be initialized with an initializer
• Better to initialize variables during declaration to avoid bugs
• Some compilers don’t allow read operation from an uninitialized
variable
Poash® Technologies
Functions
• A function is a set of statements enclosed within a
pair of { }
• Called as body of the function
• These statements define what the function does
• Every function has a unique name
• This name is used to invoke or call the function
• Functions are basic building blocks of C/C++ programs
Poash® Technologies
Why Functions
• Help avoid writing repetitive logic/code in a program
• Same code can be reused in different parts of the program through a
function
• There’s no limit to the number of times a function can be called
• Makes the code modular as the program is divided can be divided into
cohesive modules
• Reduces complexity of the code
Poash® Technologies
Structure
• A function can accept values through parameters
• These can be used as input for some processing inside the function
• Afterwards, a function can return the result of processing as the return value
• Only one value can be returned
• Parameters and return value are optional
Structure
• To use a function, you’ve to call or invoke it
• If a function has parameters, you’ve to supply the corresponding
arguments
Console I/O
• std::basic_ostream & std::basic_istream
• std::ostream & std::istream
• std::cout & std::cin
• std::cout for console output through operator <<
• std::cin for keyboard input through operator >>
• <iostream> header
Poash® Technologies
Uniform Initialization
• C++98 provided different ways to initialize types
• Scalar types can be initialized with = or ()
• Array types have to be initialized with {}
• C++11 introduced uniform initialization
• Use {} to initialize all types
Poash® Technologies
Advantages
• Uniform syntax to initialize all types
• Forces initialization of both scalar and array types
• Prevents bugs when initializing incompatible types through compiler
warnings/errors
Poash® Technologies
auto Keyword
• Indicates storage class of a variable in C & pre-C++11
• Remnant of B language (which largely influenced C)
• Meaning has been changed in C++11
• Allows the compiler to automatically infer the type from the initializer
• The initializer is important
Pointer Type
Poash® Technologies
Pointer
• Points to another type
• Holds the memory address of another variable
• Used for indirect access to other variables
• Need not be initialized during declaration
• Declared with * operator
int * ptr ;
int *p1, *p2, *p3 , p4 ;
Poash® Technologies
Address Of Operator
• & is the address of operator
• When applied to any variable, we get the address of that variable (the
location where it is stored in the memory)
int x = 10 ;
cout << &x ; //prints the address of x
Poash® Technologies
Pointer Type
Memory address of x 0x100 10
int x = 10 ;
int *ptr = &x ;
RAM
Poash® Technologies
Dereference Operator
• To access the value at the address in the pointer, use the * operator
• Also called dereference operator
• Allows indirect read or write operation on the variable through the
pointer
int x = 10 ;
int *ptr = &x ;
*ptr = 5 ; //Assign 5 to address of x
int y = *ptr ; //Read a value from address of x
Poash® Technologies
Null Pointer
• NULL is a macro in C & pre-C++11
• It is defined as 0 in most compilers
• Used to initialize pointer types
• C++11 introduced a new type of null called nullptr
• This is type safe and better than NULL macro
• Always use nullptr to initialize a pointer, instead of NULL macro
Poash® Technologies
Reference Type
• Defines an alternative name for a variable (an alias)
• It is created with the & operator during declaration
• Always needs an initializer (called referent)
• The referent should be a variable
• It is bound to its referent
• It can be used to modify a variable indirectly (like a pointer)
• A reference is NOT a new variable; it is just another name
Poash® Technologies
Reference Type
int x = 10 ;
x ref
int &ref = x ; //x is the referent
RAM
Poash® Technologies
Reference Vs Pointer
Reference Pointer
• Always needs an initializer • Initializer is optional
• Initializer should be l-value • Initializer need not be lvalue
• Cannot be nullptr • Can be nullptr
• Bound to its referent • Can point to other variables
• No storage required, so has • Has its own storage, so will have a
same address as that of referent different address
• Dereference not required • Requires dereference operator to
access the value
Poash® Technologies
const Qualifier
• Creates a variable that is constant
• Value cannot be modified
• Attempt to modify will cause compilation error
• Qualified to a declaration, but always needs an initializer
• Replaces C macros
• Commonly used with references
Function Overloading
• Two or more functions declared with the same name
• Arguments should differ in type and/or number
• For pointers & reference arguments, qualifiers participate in overload
• Return type is ignored
• For member functions, qualifiers participate in overload
• Different implementations of the same behaviour
• The correct implementation is chosen based on the arguments
• This is resolved at compile-time
• static polymorphism
• Convenience for the caller
Poash® Technologies
Name Mangling
• Unique names generated by the compiler for functions
• Allows linker to link the call with the correct overloaded
function
• Name mangling algorithm varies from compiler to compiler
• Depends on the type & number of function arguments
• Consequently, C++ functions are not callable from C code
Poash® Technologies
extern “C”
• Compiler directive applied on global functions and variables
• Suppresses name mangling of the type on which it is applied
• Can be applied only to one function in a set of overloaded functions
• Allows C++ functions to be called from C or other languages
Inline Function
• A function that is marked with inline keyword
• Such functions are defined in a header file
• Requests the compiler to replace the call with the function body
• The overhead of the function call is avoided
• Stack memory for arguments not required
• No need to save the return address
• May improve the performance of the code
Points
• Only a request to the compiler
• Certain functions may not be inlined
• large functions
• functions having too many conditional statements
• recursive functions
• functions invoked through pointers
• etc
• Different compilers have different rules
• Modern compilers may automatically inline even non-inline functions
• Excessive inlining may increase binary size
Poash® Technologies
Function Pointer
• Pointer that holds the address of the function
• The type is same as the signature of the function (return type
& arguments)
• Can be used to indirectly invoke the function even if the
function name is not known
• Used by algorithms and classes for customization
<ret> (*fnptr)(args) = &Function
int (*PtrAdd)(int,int) = &Add //int Add(int,int)
Poash® Technologies
Namespace
• Named declarative region used for declaring types
• The types are not visible outside the namespace
• Standard library is in std namespace
• Prevents name clashes
• Helps modularize code
namespace <name> {
(namespace, class, structure, function, variable, etc)
}
Poash® Technologies
Namespace Access
• Types inside a namespace have a scope
• Cannot be accessed outside the namespace
• Either open the namespace or the type
• use the global using declarative and open the entire namespace
using namespace std ;
• use the using declarative and open a specific type
using std::cout ;
• using the full qualified name
std::cout << “C++” << std::endl;
Poash® Technologies
Memory Management
• C/C++ programs are provided with different types of memory areas
• stack – allocated automatically for local variables
• data section – allocated for global and static data
• heap – allocated at runtime
• All the memory is taken from the process address space
• C/C++ programs provide support for memory allocation at runtime
(also called dynamic memory)
• Allocations on the heap have to be managed by the programmer
• Stack and data section allocations are managed by the runtime
Poash® Technologies
malloc vs new
malloc new
• Function • Operator
• Requires size during allocation • Size is ascertained from the type
• Cannot initialize memory • Can initialize memory
• Cannot call constructors • Can call constructors
• Returns void pointer that needs to • Returns correct type of pointer
be type casted • Can be customized through
• Cannot be customized overloading
• malloc, calloc & realloc • Has different forms
• Return NULL on failure • Throws exception on failure
Poash® Technologies
Important Points
• Always use as a pair
• Not calling delete causes a memory leak
• Responsibility of the programmer to release the
memory
• Do not mix malloc and new in same code
Poash® Technologies
Object Model
• Basic principles that help us write OO programs
• Abstraction
• Encapsulation
• Inheritance
• Polymorphism
Umar Lone 61
Poash® Technologies
Abstraction
• Abstraction focuses on important & necessary details
• Unwanted features are left out
• e.g. name of a person without other details (age, weight, etc)
• Helps focus on important characteristics
• Used to represent real-life objects in software, but without the
associated complexity
• Represented through a class, struct, interface, union or enum
Umar Lone 62
Poash® Technologies
Encapsulation
• Next step after abstraction
• Hides the implementation details of a class
• The class provides behaviour without revealing the implementation
• Objects of such classes are easy to use
• The internal implementation can be changed without the users’
knowledge
• Implemented through access modifiers in OO languages
Umar Lone 63
Poash® Technologies
Inheritance
• Represents a hierarchy of classes
• The classes are related through “is-a” relationship
• The relation is due to same behaviour of classes
• e.g. a dog is an animal
• The behaviour & its implementation is inherited by the children from
the parent
• The child classes may then reuse the behaviour with the same
implementation or provide a different implementation
• Promotes reuse & extensibility
Umar Lone 64
Poash® Technologies
Composition
• Signifies relationship between objects
• Represented as “has-a” or “part-of” relationship
• Promotes reuse of objects
• e.g. car has an engine
Umar Lone 65
Poash® Technologies
Polymorphism
• Means different forms
• Represents common behaviour with different implementations
• Response will be different for each object, either based on its class or
the arguments
• e.g. car, cycle, person, etc. can move differently
• Implemented through function overloading, templates & virtual
functions
• Used in conjunction with inheritance & composition
• Promotes reuse, scalability & extensibility
Umar Lone 66
Poash® Technologies
class
• Blueprint/template/recipe
• Represents an abstraction
• Every object is instantiated
• Instance of a class
• Can have multiple instances
• Objects are independent
Umar Lone 67
Poash® Technologies
Syntax
class <name> {
//Members are private by default
<modifiers>:
<member variables>
<member functions>
};
Umar Lone 68
Poash® Technologies
Example
class Car {
private:
float fuel ;
float speed ;
int passengers ;
public:
void FillFuel(float amount) ;
void Accelerate() ;
Umar Lone 69
Poash® Technologies
Structure
• Creates a user-defined type through keyword struct
• Similar to a class
• Default access is public
• Frequently used
• to represent simple abstract types such as point, vector3D, etc.
• for implementing function objects
Umar Lone 70
Poash® Technologies
Constructor
• Invoked automatically during instantiation
• Used for initialization
• Doesn’t have any return type
• Can be overloaded
• Default
• Parameterized
• Copy
• Delegating
• Inheriting
Umar Lone 72
Poash® Technologies
Default Constructor
• Constructor with no arguments
Umar Lone 73
Poash® Technologies
Parameterized Constructor
• Constructor that accepts one or more arguments
• Used to initialize the object with user-defined values
• Never synthesized by the compiler
• Blocks auto generation of default constructor
Umar Lone 74
Poash® Technologies
Destructor
• Function that is invoked automatically when an object is destroyed
• Used for releasing resources that may have been allocated in the
constructor
• Cannot be overloaded
• No arguments
• Compiler synthesizes one if required
Umar Lone 75
Poash® Technologies
this Pointer
• A hidden pointer passed to member function
• Points to the object that invoked the member function
• Provided as a keyword that is meaningful only in member functions
• Can be used to access members inside the member functions
Umar Lone 76
Poash® Technologies
Umar Lone 77
Poash® Technologies
//Car.h //Car.cpp
class Car{ int Car::totalCars ; //Default init to 0
static int totalCars ;
Umar Lone 78
Poash® Technologies
Umar Lone 79
Poash® Technologies
Umar Lone 80
Poash® Technologies
struct
• Similar to a class
• Supports everything that a class does
• Members are public by default
• Used for creating abstract data types & function objects
Umar Lone 81
Poash® Technologies
Delegating Constructor
• Allows a constructor to invoke another constructor
• Replacement for common initialization
• Reduces duplicate initialization code in multiple constructors
class Class{
Class():Class(val1, val2){
Class(arg1, arg2){
//Initialization code
Umar Lone 82
Poash® Technologies
Copy Constructor
• Creates copy of the object’s state in another object
• Synthesized automatically
• Default implementation copies values
• User-defined implementation required for pointer members
Umar Lone 83
Poash® Technologies
Rule Of 3
• All should be defined if a user implements any of them
• Destructor
• Copy constructor
• Copy assignment operator
• This will be due to allocation of some resource in a constructor
• Destructor will free the resource
• Copy constructor will perform a deep copy
• Copy assignment operation will also perform a deep copy
• Not implementing user defined operations can lead to memory leak
or shallow copy
Umar Lone 84
Poash® Technologies
L-value R-value
• Has a name • Does not have a name
• All variables are l-values • R-value is a temporary value
• Can be assigned values • Cannot be assigned values
• Some expressions return l-value • Some expressions return r-value
• L-value persists beyond the expression • Does not persist beyond the expression
• Functions that return by reference • Functions that return by value return r-
return l-value value
• Reference to l-value (called l-value • R-value reference to r-value (called r-
reference) value reference)
Umar Lone 85
Poash® Technologies
R-Value References
• A reference created to a temporary
• Represents a temporary
• Created with && operator
• Cannot point to l-values
• R-value references always bind to temporaries
• L-value references always bind to l-values
Umar Lone 87
Poash® Technologies
Copy Semantics
obj1
v 0x100 …
ptr 0x104 5
obj2
v 0x200 …
ptr 0x204 5
Umar Lone 88
Poash® Technologies
Move Semantics
0x0 …
....
obj1
v 0x100 …
ptr 0x104 5
obj2
v
ptr
Umar Lone 89
Poash® Technologies
Rule Of 5
• All should be defined if a user implements any of the
following
• Destructor
• Copy constructor
• Copy assignment operator
• Move constructor
• Move assignment operator
Umar Lone 90
Poash® Technologies
Rule of 0
• If a class does not have ownership semantics, then do not provide any
user defined function from the rule of 5
• This is called the “rule of 0”
• This way the compiler will automatically synthesize the necessary
functions
• Providing user-defined implementation of some functions will prevent
the compiler from synthesizing others
Poash® Technologies
Operator Overloading
• Custom implementation for primitive operators
• Allows usage of user-defined objects in mathematical expressions
• Overloaded as functions but provide a convenient notation
• Implemented as member or global functions
• Require usage of the operator keyword
Umar Lone 94
Poash® Technologies
Operator Overloading
• As global functions, require same no. of arguments as the operands
• As member functions, one operand is passed as argument through
this pointer
• binary operator will require only one explicit argument
• unary operator will not require any explicit argument
Umar Lone 95
Poash® Technologies
Rules
• Associativity, precedence & arity (operand count) does not change
• Operator functions should be non-static
• except for new & delete
• One argument should be user defined type
• Global overload if first operand is primitive type
• Not all operators can be overloaded
• . ?: .* sizeof
• Cannot define new operators
• Overloaded for conventional behaviour only
Umar Lone 96
Poash® Technologies
Type Conversions
• Conversion between types
• Performed through casts
• Ordered by compiler (implicit) or user(explicit)
• Explicit conversion uses casting operators
• Conversion between
• basic & basic
• basic & user-defined
• user-defined & basic
• user-defined & user-defined
Umar Lone 97
Poash® Technologies
No arguments
operator <type>() No return type
operator int()
Umar Lone 98
Poash® Technologies
Enumerated Type
• Type created through enum keyword
• Created with restricted range of values, called symbolic constants or enumerators
• Enumerators are internally represented as undefined integral types
• Can implicitly convert to an integer, but not the other way round
• Default value starts from 0, but users can assign any value
• Enumerators are visible in the scope in which they’re defined
enum Color(Red, Green, Blue) ;
Color c = Red ;
c = 1 ; //Compiler error, use static_cast to convert
int x = Green ;//x will contain 1
Umar Lone 99
Poash® Technologies
constexpr
• Represents an expression that is constant
• Such expressions are possibly evaluated at compile
time
• Can be applied to variable declarations or functions
• May increase the performance of the code as
computation is done at compile time
const vs constexpr
• Initialization of a const variable can be deferred until runtime
• However, a constexpr variable must be initialized at compile
time
• All constexpr variables are const, but not the other way
round
• Use const keyword to indicate the value cannot be modified
• Use constexpr to create expressions that can be evaluated at
compile time
Umar Lone 101
Poash® Technologies
std::initializer_list
• Lightweight proxy object that represents an array of objects
• Constructed automatically from a braced list of elements
• auto
• ranged for loop
• constructor
• function
• Not a true container, but has similar behaviour
• Provides access to its elements through iterators
• Defined in <initializer_list> header
std::weak_ptr
Memory Address
shared_ptr 5
std::shared_ptr<int> p{new int{5}} ;
std::weak_ptr<int> wk = p ; 10 Control block
p.reset() ;
weak_ptr
Poash® Technologies
Circular Reference
emp prj
12 2
1
Employee* Project*
m_prj m_emp
Poash® Technologies
Circular Reference
emp prj
20
1 1
0
Employee* Project*
m_prj m_emp
Poash® Technologies
Composition
• Object composed in another object
• Represents “has-a” relation
• Reuse behavior
Inheritance
• Class inherits the features of another class
• Reuse & inherit behaviour
• Represents “is-a” relationship
Animal
Eat
Speak
Run
Syntax
Access Modifiers
class Base{
private:
MemberA Inaccessible
public :
MemberB Accessible
protected:
Accessible only
MemberC to child classes
};
Access Modifiers
Object Construction
• Constructors execute from base to child
• Destructors execute from child to base
• Base data members will be part of child object
Banking Application
• Manage accounts
• Customers can perform common operations
• Bank can perform administrative tasks
• Represent account through Account class
• Common implementation for all account types
Banking Application
Account
name
accno
balance
...
Withdraw
Deposit
Savings GetBalance
Checking
AccumulateInterest
GetInterestRate
...
Polymorphism
• Different forms of the function are provided
• The call is resolved at compile time or runtime
• Runtime polymorphism or dynamic binding
• Implemented through virtual mechanism
• Compiler inserts code to invoke the correct function at runtime
• Automatically generated through the virtual keyword
• Such functions are called polymorphic functions
• Should be invoked only through a pointer or reference
Virtual Mechanism
Abstract Class
• At least one pure virtual function
• Can contain other members (data, non-virtual functions, etc.)
• Cannot be instantiated, but used through a pointer or
reference
• Establishes a contract with clients
• Used for creating interface
Multiple Inheritance
• C++ allows inheritance from more than one class
simultaneously
• Known as multiple inheritance
• Allows a class to reuse/override behaviours from multiple
classes
• Multiple inheritance can lead to diamond inheritance
• Classes inherit from a common parent (form a diamond
shape)
Umar Lone 120
Poash® Technologies
Diamond Inheritance
Stream
stream stream
instream InputStream OutputStream outstream
stream
IOStream outstream
stream IOStream object
instream
iostream
Umar Lone 121
Poash® Technologies
Diamond Inheritance
Stream
virtual virtual
stream stream
instream vptr InputStream OutputStream outstream vptr
IOStream stream
outstream vptr
IOStream object
instream vptr
iostream
Umar Lone 122
Poash® Technologies
Exception Handling
• Mechanism to handle errors in programs that occur at
runtime
• These errors are called exceptions
• Exist outside the normal functioning of the program
• Require immediate handling by the program
• If not handled, the program crashes
• Cannot be ignored, unlike C error handling
Mechanism
• try
• creates a scope/block & exception causing code appears here
• can contain other try-catch statements
• throw
• throws an exception from the try block
• exception is object that is constructed in throw statement
• catch
• handler that catches the exception object
• should appear just after the try block
• multiple catch blocks can exist
noexcept
• Applied to functions (both in declaration & definition)
• Indicates the function does not throw exceptions
• Compiler can optimize the function code
• no need to generate stack unwinding code
• An exception from such function terminates the program
• stack may or may not be unwinded
• Not all functions should use noexcept specifier
• especially functions calling other functions (in library)
• such functions will be exception-neutral
<filesystem>
• Contains the filesystem support library with following classes
• Exist under std::experimental::filesystem namespace
Class Purpose
path represents a path
filesystem_error exception representing file system errors
directory_iterator iterator to the contents of a directory
file_status represents file type and permissions
File I/O
• C++ provides support for file I/O through following classes
• ofstream – write to an output stream
• ifstream – read from an input stream
• fstream – write/read stream
• Include <fstream> header
• All classes can be used for both text & binary I/O
• Additionally, they support modes that decide how the file is
opened and operated
• is_open() function returns a boolean indicating if a stream is open
Umar Lone 128
Poash® Technologies
Stream Classes
istream ostream
fstream stringstream
Templates
• Generalizes software components
• Such components can be reused in different situations
• Operate of any kind of data
• High performance algorithms & classes
• Compile time; no runtime costs are involved
• Libraries such as ATL, WTL, Boost, POCO, ACE, etc. use templates for
implementation
Function Templates
• Function that accepts template type Template parameter list
arguments
template<typename T>
• Always begins with template keyword
T Function(T arg){
• Template type argument is called type name //Implementation
• Type name is a placeholder for the actual type }
• Can accept any type
• The template type can be used as return type
Template Instantiation
• A template function or class only acts as a blueprint
• The compiler generates code from the blueprint at compile time
• Known as template instantiation
• Occurs implicitly when
• a function template is invoked
• taking address of a function template
• using explicit instantiation
• creating explicit specialization
• Full definition of template should be available
• Define in header file
Umar Lone 136
Poash® Technologies
Explicit Specialization
• Template specialized for a particular type
• Provides correct semantics for some datatype
• Or implement an algorithm optimally for a specific type
• Explicitly specialized functions must be defined in a .cpp file
• Primary template definition should occur before
specialization
Example
Umar Lone 140
Poash® Technologies
Type Alias
• Creates a name that is a synonym of existing type
• Does not introduce a new type
• Same as a typedef declaration
• Created through the using keyword
Example
Umar Lone 142
Poash® Technologies
Function Object
• Object with overloaded function call operator
• Call to overloaded function call operator resembles a global
function call
• Can be used as a callback instead of function pointers
• More efficient than function pointers
• Usually implemented as structs
Lambda Expressions
• Defines an anonymous function object
Lambda Expressions
• Typically, encapsulates a few lines of code
Syntax
Lambda
Introducer
[](<args>) <mutable> <excp specification> -> <return type>
{
Lambda
Body
}
[var=expression](args)
[&var=expression](args)
Poash® Technologies
Core Components
• Container classes, algorithms & iterators form the core
components of the STL
• Container classes represent data & algorithms represent
operations on the data
• Iterators serve as the glue between containers and
algorithms
• Also includes classes for concurrency, random numbers,
regular expressions, utilities, etc.
Container Types
Sequence Header
array <array>
Common functions
vector <vector>
list <list>
• default constructor
deque <deque>
• uniform initialization constructor
forward_list <forward_list>
• copy constructor
Associative Header
• iterator constructor
set, multiset <set>
• size()
map, multimap <map>
• clear()
Unordered Header
• begin()
unordered_set, unordered_multiset <unordered_set>
• end()
unordered_map, unordered_multimap <unordered_map>
• default allocator
Umar Lone 153
Poash® Technologies
Iterators
• Pointer like objects
• Used to access elements by their position
• Provide overloaded operators, such as ++, --, *, etc
• Created through begin() & end() functions in all containers
begin end
std::array
• Thin wrapper over C-style static array
• Supports iterators
• Knows about its size
• Provides random access
• Can be used with C functions
• Cannot grow
std::vector
• Behaves like a dynamic array
• Grows automatically
• Efficient for addition/removal at the end
• Provides random access
• Not good for insertion/deletion
std::deque
• Efficient for addition/removal at the both ends
• Grows automatically
• Provides random access
• Not good for insertion/deletion
std::list
• Implemented as a two-way linked list
• Efficient for insertion/deletion anywhere
• Does not provide random access
std::forward_list
• Implemented as a one-way linked list
• Small memory footprint
• Efficient for insertion/deletion
• Does not provide support for size
• Elements are added at the front
std::set/std::multi_set
• Implemented as a binary tree
• Elements are stored in sorted order (< & >)
• Value acts as key
• Fast search
• No random access
• Elements cannot be modified directly
std::map/std::multi_map
• Implemented as a binary tree
• Stores a pair that contains a key and value Key Value
Unordered Containers
• Associative containers implemented as hash tables
• Values are hashed and stored in undefined order
• Fast search, insertion/deletion, but may degrade over a period of time
• std::unordered_set stores values that act as keys for hashing
• std::unordered_map stores pairs (first is used to compute hash)
• Iterators are constant
Implementation
Buckets Entries
Insert Element
Hash
Function
Complexity
• Amount of time taken by an algorithm to run for input of size
n
• Commonly, represented through Big-O notation e.g.
• O(1) represents constant time
• O(n) represents linear time
• Gives a rough idea about the performance of an algorithm
• Useful for large input size
Container Changes
• All member functions that create an iterator are noexcept
• New member functions, such as emplace(), emplace_back(),
emplace_front() in containers, support for brace list initialization
• Containers are move aware and will prefer move over copy
• In std::vector, new functions were added - data(), shrink_to_fit()
• std::erase added for sequence containers
• Associative containers got new functions – emplace_hint(), extract(),
contains()
Poash® Technologies
Complexity of Operations
Container [] push_back pop_back insert erase find sort
array O(1) O(n) O(n log n)
vector O(1) O(1) O(1) O(n) O(n) O(n) O(n log n)
deque O(1) O(1)* O(1)* O(n) O(n) O(n) O(n log n)
list NA O(1) O(1) O(1) O(1) O(n) O(n log n)
forward_list NA NA* NA* O(1) O(1) O(n) NA
set/multiset NA NA NA O(log n) O(log n) O(log n) NA
map/multimap NA NA NA O(log n) O(log n) O(log n) NA
unordered_set/ NA NA NA O(1) O(1) O(1) NA
unordered_multiset
unordered_map/ NA NA NA O(1) O(1) O(1) NA
unordered_multimap
Summary
• Use vector for random access, but not insertion & deletion
• deque is preferable when elements need to be inserted and removed
from both the ends
• Use list if frequent insertions & deletions are required
• Use forward_list for memory constrained systems
• Use associative containers if lookup/search is important
• Favour unordered containers if elements need not be ordered, else
use set/map
Algorithms
• STL provides algorithms for common tasks
• Sorting, removing, searching, numeric, etc
• More optimized than handwritten loops
• Work with all containers regardless of the data type
• Several algorithms can be customized through user-defined operations
• Some containers provide specialized versions of algorithms
• list provides sort & remove
• associative containers provide lower_bound, upper_bound, find, etc
• Most algorithms reside in <algorithm> header
C++ Concurrency
• Large applications have multiple components
• Some components may have to execute concurrently
• This allows efficient usage of the CPU
• C++11 added support for concurrency
• Includes utilities for starting and managing threads
std::thread
• Accepts a callable as constructor argument
• The callable is executed in a separate thread
• The constructor does not wait for the thread to start;
it returns immediately
• Resides in <thread> header
std::async
• Part of high-level concurrency
• Executes a callable object or a function in a separate
thread (if possible)
• Returns a std::future object that provides access to
the result of the callable
• Include the header <future>
std::future
• Used for communication between threads
• Created through std::promise
• created by std::async, that directly returns a future object
• represents an input channel
• std::future is the output channel
• Promise/future pair allow safe data sharing between
threads
Removed Features
• register keyword
• Exception specifications
• operator++(bool)
• Trigraphs
• auto_ptr
• Library Functions
Poash® Technologies
register Keyword
• A hint that specifies the variable should be stored in a register
• This storage class is now removed in C++17
• It has no effect on the semantics of the program
void RegisterKeyword() {
register int x ;
x = 5 ;
}
Poash® Technologies
operator++(bool)
• Increment operator on a bool type is removed
• Decrement operators were never allowed
int main() {
bool x{} ;
x++ ;
}
Poash® Technologies
Trigraphs
• Special character sequences used when a system does not support 7-
bit ASCII
• E.g. ??- produced ~
• These have been removed to speed up the compilation process
Poash® Technologies
Exception Specifications
• Feature that allowed a function to advertise what exceptions it throws
• Not implemented by many compilers
• Replaced by noexcept
std::auto_ptr
• Smart pointer in C++98
• No ownership semantics
• Could lead to bugs
• Replaced with std::unique_ptr & std::shared_ptr
Poash® Technologies
Library Functions
• std::random_shuffle
• std::unary_function
• std::ptr_fun
• std::bind1st….
https://isocpp.org/files/papers/p0636r0.html
Poash® Technologies
Changes
• Direct list initialization with auto
• static_assert
• Different begin & end types on range-based for loop
Poash® Technologies
Expansion
std::array<int, 5> values{ 1,2,3,4,5 };
for (auto v : values) {
//Use v
}
//Pseudo code
auto && range = values ;
auto begin = std::begin(range);
auto end = std::end(range); //Can be of a different type in C++17
Type Traits
• Type traits give the ability to introspect
• find the characteristics of types at compile time
• transform the properties of the type
• Useful in template metaprogramming
• Will either return a boolean or a type when inspecting types
• Provides template-based interface and defined in header
<type_traits>
• Some traits require support from the compiler
• compiler provides intrinsics for such traits
186
Poash® Technologies
Type Traits
Poash® Technologies
static_assert
• In C++17, static_assert can have a condition without a message
int main() {
int x {} ;
CheckPointer(x) ; //Causes assertion
CheckPointer(&x) ;
}
Poash® Technologies
Evaluation Order
• In previous standards, the evaluation order of sub-expressions in
function parameters was unpredictable
• In the following statement, it is unspecified in which order the
functions will be invoked
using namespace std ;
cout << a() << b() << c() ;
cout.operator<<(a()).operator<<(b()).operator<<(c());
1 2 3
4 5 6
Poash® Technologies
Evaluation Order
void F(
std::unique_ptr<int> p1,
std::unique_ptr<int> p2) {
//Implementation
}
int main() {
F(
std::unique_ptr<int> //1 Pre-C+ C++17
{new int}, //2 +17
std::unique_ptr<int> //3 2, 4, 1, 3 2, 1, 4, 3
{new int} //4
) ; 4, 2, 3, 1 4, 3, 2, 1
}
Poash® Technologies
Exception Specification
• Exception specification for a function was not part of the function
signature/type
• In C++17, it is part of the function’s type
Poash® Technologies
Structured Bindings
• Allows initialization of multiple variables with the elements or
members of an object
• The object could be object of a class/struct or an array
• For objects of classes, the members should be public
• The number of variables should match with the number of elements
in the object
auto [variables] = object ;
<cv qualifiers> auto &[variables] = object ;
Poash® Technologies
Structured Bindings
• Creates an anonymous entity which is a copy of the object
• This anonymous entity cannot be accessed directly
• We can only access the members through the structured binding
• Useful when you want to read the data of each member to separate
variables (or assign)
• Makes the code more readable by binding the value directly to a
name that conveys the real purpose of the data
Poash® Technologies
Example
Person p ;
auto [n, a] = p ; //Creates an alias(copy) of p
//Create a reference
auto &[n1, a1] = p ;
//Apply qualifiers
const auto &[n2, a2] = p ;
Poash® Technologies
if-switch Initialization
• C++17 added the ability to initialize and compare variables in if &
switch statements
• These statements have an initialization clause in addition to
conditional or select clause
• Avoids creation of local variables that leak to the entire scope
if(initialization clause; condition clause){
}
switch(initialization clause; select clause){
}
195
Poash® Technologies
Global Variables
• In C++, a global name can be defined only once (ODR)
• E.g. you should avoid defining a global variable in a header file
• If the header file is included in multiple .cpp files, it would cause linker
errors (violates ODR)
• To avoid this, the global variable is defined in one of the .cpp files and
declared extern in others
• This satisfies ODR
• In C++17, you can now define a variable in a header file without ODR
errors through the inline keyword
Poash® Technologies
Inline Variables
• inline on a global variable implies it can have multiple definitions
• The linker will treat it as only on variable even if it is encountered in
multiple .cpp files
• However, all the definitions must be exactly same
• The definition of an inline variable should be accessible by the
compiler before it can be used
• All the instances of the inline variable will have the same address
Poash® Technologies
Nested Namespace
• Namespaces can be nested with a simple syntax in C++17
• Instead of using the namespace keyword on each nested namespace,
you can now use scope resolution operator
namespace A {
namespace B {
namespace C {
namespace A::B::C {
}
} }
}
C++14 C++17
Poash® Technologies
Attributes
• Attributes used to be compiler-specific commands that give additional
information to the compiler
• They might be utilised for optimization or checks
• Before C++11, different compiler vendors used keywords for attributes
e.g. MSVC uses __declspec, GCC uses __attribute, etc
• C++11 introduced some standardized attributes that work with all
standard-compliant compilers
• C++14 & C++17 introduced more attributes that you can use in your code
• You cannot create custom attributes
Poash® Technologies
Common Attributes
Attribute Meaning Use
[[noreturn]] Indicates the function does not return (C++11) Function
[[deprecated(””)]] The entity is deprecated but can be used (C++14) variables, classes, typedefs,
functions, namespaces
[[nodiscard]] The return value should not be discarded (C++17) function, class, enum, variable
declaration
[[maybe_unused]] Prevents compiler for issuing warnings on non- class, variables, enum declarations
used entities (C++17) & functions
[[fall_through]] Indicates deliberate fall through in a case switch-case
statement (C++17)
201
Poash® Technologies
Lambdas
• Two additions were made in C++17 in regards to lambda expressions
• they can be constexpr (although the specifier is not required)
• capture of *this
Poash® Technologies
Modern C++
Poash® Technologies
Folding
• It is process that applies a binary operator to a list of values
recursively
• The results are combined recursively, that builds up the final result
• This process is called as folding
• Variadic templates can perform folds over a template parameter pack
• However, it requires overloads with recursion
• needs to unpack the parameters for processing
Poash® Technologies
Fold Expressions
• C++17 offers a new way to unpack variadic parameters with binary
operators
• This is call fold expression
• A fold expression reduces(folds) a parameter pack over a binary
operator
• This is a compact syntax for applying binary operations to the
elements of a parameter pack
• Simplifies implementation of variadic templates that have to apply
binary operators on a parameter pack
Poash® Technologies
Fold Expressions
• The following syntax is provided for fold expressions
• (pack op …) :unary right fold
• (… op pack) :unary left fold
• (pack op … op init):binary right fold
• (init op … op pack):binary left fold
• pack is unexpanded parameter pack
• op is operator – can be any of the 32 binary operators
• init is a value
207
Poash® Technologies
Fold Expressions
• The following syntax is provided for fold expressions
• (pack op …) :unary right fold
• (… op pack) :unary left fold
• (pack op … op init):binary right fold
• (init op … op pack):binary left fold
• pack is unexpanded parameter pack
• op is operator – can be any of the 32 binary operators
• init is a value
208
Poash® Technologies
Compile-Time if
• This feature allows the condition of an if statement to be evaluated at compile time
if constexpr(condition)
Compile-Time if
• Only the block that follows the true condition is evaluated; the else
blocks become discarded statements
std::optional
• A new library type that can be used when a function may or may not
return a value
• If it does not return a value, a common way is to compare with a
predefined value such as 0, nullptr, true/false, etc
• This leads to different kinds of checks for different types
• std::optional<T> can represent a type that may or may not contain a
value
• often called a nullable type
Poash® Technologies
Properties
• No value is represented by std::nullopt
• std::optional is a value type – so, it can be copied through deep copy
• Does not need to allocate any memory on heap
• You cannot store references inside std::optional
• Provides several overloaded operators and functions to access the
value inside safely
• May throw std::bad_optional_access
Poash® Technologies
Unions in C++
• Gives the ability to represent all the members in the same memory
• Saves space
• However, it has several disadvantages
• no way to know which type it holds
• nested types with non-default constructors deletes the default constructor of
the union
• cannot assign objects of user-defined types directly to a union member
• user-defined types are not destroyed implicitly
• cannot have a base class
• cannot derive from a union
Poash® Technologies
std::variant
• std::variant is a type-safe replacement for union type
• Just like union, it uses the storage of the largest member
• The first member is always default initialized if variant is default
constructed
• Alternatively, you can initialize any member of the variant during
construction
• Members are destroyed properly
• Throws bad_variant_access on invalid access
Poash® Technologies
std::variant
• Type of the current value is always known
• It can hold values of any specified type
• Always holds a value (except in some rare situations)
• You can derive from it
• Doesn’t require heap memory
• Easily initialize or assign a new value to a member
• Members are automatically destroyed
Poash® Technologies
Type Safety
• C++ is a strongly typed language
• Object are declared with a specific type and that cannot be changed later
• In some cases, we may require an object that should hold values of
different types
• This is difficult to achieve in C++, except through void *
• However, such pointers have certain disadvantages
• Not typesafe
• No way to know the type
• Cannot access the value in a type-safe way
• Need to manage the object lifetime
Poash® Technologies
std::any
• C++17 introduced std::any
• A wrapper that can hold value of any arbitrary type in a type-safe way
• Replacement for void *
• Contains both the value & its type
• The value is accessed through any_cast<>
• May allocate memory on the heap
• Throws exception of type bad_any_cast on wrong type access
Poash® Technologies
std::string_view
• Allows us to deal with character sequences without allocating memory
• Can be considered as a kind of reference to a character sequence
• Can be used where ever a non-modifiable string is required
• It simply stores a pointer to the character array along with its length
• It is fast and cheap to copy
• However, it should be used carefully as it can lead to bugs
length –4
std::string_view data – 0x123 a s t r i n g i n
Poash® Technologies
Properties
• Underlying sequence is read-only
• It can be accessed through data() method
• may return a nullptr
• a character sequence without null terminator
• You can only assign a new value, swap values and shrink it to a subset
of character sequence
• Character sequence is not guaranteed to be null-terminated
• consequently, may not work with C string functions
• No allocator support
Poash® Technologies
Filesystem
• C++17 added support for working with filesystem components
• Adopted from Boost.Filesystem, it was adjusted to new language
standards and made consistent with other parts of the library
• Provides facilities for performing following operations
• manipulation of filesystem paths
• create, move, rename, delete directories
• list contents of a given directory
• get information about path, file permissions, etc
• To create, read & write files, you’ll still use the stream library classes
Poash® Technologies
Filesystem
• The facilities are provided in <filesystem> header under std::filesystem
namespace
• path – allows manipulation of paths that represent existing files or directories
• directory_entry – represents a path with additional information such as file
size, file times, etc
• directory_iterator – an iterator that iterates over the contents of a directory
• functions for working with directories
• and much more
• Many functions will throw std::filesystem_error exception on failure
Poash® Technologies
Syntax
• Parallel versions of STL algorithms have a simple interface
• They are provided as overloaded functions with the first parameter
signifying the execution policy
• Execution policy defines how the algorithm should execute
Execution Policies
• All execution policies existing in <execution> header and in std::execution namespace
• Each of the policy is an individual type
• sequenced_policy - seq
• the algorithm’s execution will not be parallelized and will perform operations sequentially
element by element
• same as invoking the algorithms from C++14
• parallel_policy - par
• indicates the algorithm should execute parallelly
• might use threads from a thread pool for execution along with the calling thread
• parallel_unsequenced_policy – par_unseq
• indicates the execution may be parallelized, vectorized or migrated across threads
Poash® Technologies
Parallelized Algorithms
std::adjacent_difference std::is_partitioned std::reverse
std::adjacent_find std::is_sorted std::reverse_copy
std::all_of std::is_sorted_until std::rotate
std::any_of std::lexicographical_compare std::rotate_copy
std::copy std::max_element std::search
std::copy_if std::merge std::search_n
std::copy_n std::min_element std::set_difference
std::count std::minmax_element std::set_intersection
std::count_if std::mismatch std::set_symmetric_difference
std::equal std::move std::set_union
std::fill std::none_of std::sort
std::fill_n std::nth_element std::stable_partition
std::find std::partial_sort std::stable_sort
std::find_end std::partial_sort_copy std::swap_ranges
std::find_first_of std::partition std::transform
std::find_if std::partition_copy std::uninitialized_copy
std::find_if_not std::remove std::uninitialized_copy_n
std::generate std::remove_copy std::uninitialized_fill
std::generate_n std::remove_copy_if std::uninitialized_fill_n
std::includes std::remove_if std::unique
std::inner_product std::replace std::unique_copy
std::inplace_merge std::replace_copy
std::is_heap std::replace_copy_if
std::is_heap_until std::replace_if
Poash® Technologies
New Algorithms
for_each
for_each_n
reduce
exclusive_scan
inclusive_scan
transform_reduce
transform_exclusive_scan
transform_inclusive_scan
Poash® Technologies
Exception Handling
• If an element access function throws an exception which is not
handled, all parallel algorithms call std::terminate
• This also applies if sequential execution policy is chosen
• If you want to handle exceptions, use the standard algorithms instead
• Parallel algorithms themselves may throw std::bad_alloc if they fail to
acquire memory during execution
Poash® Technologies