100% found this document useful (1 vote)
1K views897 pages

Cplusplus

cplusplus

Uploaded by

EmreKovancı
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
1K views897 pages

Cplusplus

cplusplus

Uploaded by

EmreKovancı
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 897

C++

#c++
Table of Contents
About 1

Chapter 1: Getting started with C++ 2

Remarks 2

Versions 2

Examples 2

Hello World 2

Analysis 2

Comments 4

Single-Line Comments 4

C-Style/Block Comments 4

Importance of Comments 5

Comment markers used to disable code 5

Function 6

Function Declaration 6

Function Call 7

Function Definition 7

Function Overloading 8

Default Parameters 8

Special Function Calls - Operators 8

Visibility of function prototypes and declarations 9

The standard C++ compilation process 10

Preprocessor 11

Chapter 2: Alignment 13

Introduction 13

Remarks 13

Examples 13

Querying the alignment of a type 13

Controlling alignment 14

Chapter 3: Argument Dependent Name Lookup 15


Examples 15

What functions are found 15

Chapter 4: Arithmitic Metaprogramming 17

Introduction 17

Examples 17

Calculating power in O(log n) 17

Chapter 5: Arrays 19

Introduction 19

Examples 19

Array size: type safe at compile time. 19

Dynamically sized raw array 20

Expanding dynamic size array by using std::vector. 21

A fixed size raw array matrix (that is, a 2D raw array). 22

A dynamic size matrix using std::vector for storage. 23

Array initialization 25

Chapter 6: Atomic Types 27

Syntax 27

Remarks 27

Examples 27

Multi-threaded Access 27

Chapter 7: Attributes 29

Syntax 29

Examples 29

[[noreturn]] 29

[[fallthrough]] 30

[[deprecated]] and [[deprecated("reason")]] 31

[[nodiscard]] 31

[[maybe_unused]] 32

Chapter 8: auto 34

Remarks 34

Examples 34

Basic auto sample 34


auto and Expression Templates 35

auto, const, and references 35

Trailing return type 36

Generic lambda (C++14) 36

auto and proxy objects 37

Chapter 9: Basic input/output in c++ 38

Remarks 38

Examples 38

user input and standard output 38

Chapter 10: Basic Type Keywords 40

Examples 40

int 40

bool 40

char 40

char16_t 40

char32_t 41

float 41

double 41

long 41

short 42

void 42

wchar_t 42

Chapter 11: Bit fields 44

Introduction 44

Remarks 44

Examples 45

Declaration and Usage 45

Chapter 12: Bit Manipulation 46

Remarks 46

Examples 46

Setting a bit 46

C-style bit manipulation 46


Using std::bitset 46

Clearing a bit 46

C-style bit-manipulation 46

Using std::bitset 47

Toggling a bit 47

C-style bit-manipulation 47

Using std::bitset 47

Checking a bit 47

C-style bit-manipulation 47

Using std::bitset 48

Changing the nth bit to x 48

C-style bit-manipulation 48

Using std::bitset 48

Set all bits 48

C-style bit-manipulation 48

Using std::bitset 48

Remove rightmost set bit 48

C-style bit-manipulation 48

Counting bits set 49

Check if an integer is a power of 2 50

Bit Manipulation Application: Small to Capital Letter 50

Chapter 13: Bit Operators 52

Remarks 52

Examples 52

& - bitwise AND 52

| - bitwise OR 53

^ - bitwise XOR (exclusive OR) 53

~ - bitwise NOT (unary complement) 55

<< - left shift 56

>> - right shift 57

Chapter 14: Build Systems 58


Introduction 58

Remarks 58

Examples 58

Generating Build Environment with CMake 58

Compiling with GNU make 59

Introduction 59

Basic rules 59

Incremental builds 60

Documentation 61

Building with SCons 61

Ninja 62

Introduction 62

NMAKE (Microsoft Program Maintenance Utility) 62

Introduction 62

Autotools (GNU) 63

Introduction 63

Chapter 15: C incompatibilities 64

Introduction 64

Examples 64

Reserved Keywords 64

Weakly typed pointers 64

goto or switch 64

Chapter 16: C++ Containers 65

Introduction 65

Examples 65

C++ Containers Flowchart 65

Chapter 17: C++ Debugging and Debug-prevention Tools & Techniques 68

Introduction 68

Remarks 68

Examples 68

My C++ program ends with segfault - valgrind 68


Segfault analysis with GDB 70

Clean code 71

The use of separate functions for separate actions 72

Using consistent formatting/constructions 73

Point attention to the important parts of your code. 73

Conclusion 73

Static analysis 73

Compiler warnings 74

External tools 74

Other tools 75

Conclusion 75

Safe-stack (Stack corruptions) 75

Which parts of the stack get moved? 75

What is it actually used for? 75

How to enable it? 75

Conclusion 76

Chapter 18: C++ function "call by value" vs. "call by reference" 77

Introduction 77

Examples 77

Call by value 77

Chapter 19: C++ Streams 79

Remarks 79

Examples 79

String streams 79

Reading a file till the end 80

Reading a text file line-by-line 80

Lines without whitespace characters 80

Lines with whitespace characters 80

Reading a file into a buffer at once 81

Copying streams 81

Arrays 82
Printing collections with iostream 82

Basic printing 82

Implicit type cast 82

Generation and transformation 83

Arrays 83

Parsing files 83

Parsing files into STL containers 83

Parsing heterogeneous text tables 84

Transformation 84

Chapter 20: C++11 Memory Model 86

Remarks 86

Atomic Operations 86

Sequential Consistency 87

Relaxed Ordering 87

Release-Acquire Ordering 87

Release-Consume Ordering 88

Fences 88

Examples 88

Need for Memory Model 88

Fence example 90

Chapter 21: Callable Objects 92

Introduction 92

Remarks 92

Examples 92

Function Pointers 92

Classes with operator() (Functors) 93

Chapter 22: Classes/Structures 94

Syntax 94

Remarks 94

Examples 94

Class basics 94
Access specifiers 95

Inheritance 96

Virtual Inheritance 98

Multiple Inheritance 99

Accessing class members 101

Background 102

Private inheritance: restricting base class interface 102

Final classes and structs 103

Friendship 104

Nested Classes/Structures 105

Member Types and Aliases 109

Static class members 113

Non-static member functions 118

Unnamed struct/class 119

Chapter 23: Client server examples 122

Examples 122

Hello TCP Server 122

Hello TCP Client 125

Chapter 24: Common compile/linker errors (GCC) 127

Examples 127

error: '***' was not declared in this scope 127

Variables 127

Functions 127

undefined reference to `***' 128

fatal error: ***: No such file or directory 129

Chapter 25: Compiling and Building 130

Introduction 130

Remarks 130

Examples 130

Compiling with GCC 130

Linking with libraries: 131

Compiling with Visual C++ (Command Line) 132


Compiling with Visual Studio (Graphical Interface) - Hello World 136

Compiling with Clang 143

Online Compilers 143

The C++ compilation process 145

Compiling with Code::Blocks (Graphical interface) 147

Chapter 26: Concurrency With OpenMP 153

Introduction 153

Remarks 153

Examples 153

OpenMP: Parallel Sections 153

OpenMP: Parallel Sections 154

OpenMP: Parallel For Loop 155

OpenMP: Parallel Gathering / Reduction 155

Chapter 27: Const Correctness 157

Syntax 157

Remarks 157

Examples 157

The Basics 157

Const Correct Class Design 158

Const Correct Function Parameters 160

Const Correctness as Documentation 162

const CV-Qualified Member Functions: 162

const Function Parameters: 164

Chapter 28: const keyword 167

Syntax 167

Remarks 167

Examples 167

Const local variables 167

Const pointers 168

Const member functions 168

Avoiding duplication of code in const and non-const getter methods. 168

Chapter 29: Constant class member functions 171


Remarks 171

Examples 171

constant member function 171

Chapter 30: constexpr 173

Introduction 173

Remarks 173

Examples 173

constexpr variables 173

constexpr functions 175

Static if statement 177

Chapter 31: Copy Elision 179

Examples 179

Purpose of copy elision 179

Guaranteed copy elision 180

Return value elision 181

Parameter elision 182

Named return value elision 182

Copy initialization elision 183

Chapter 32: Copying vs Assignment 184

Syntax 184

Parameters 184

Remarks 184

Examples 184

Assignment Operator 184

Copy Constructor 185

Copy Constructor Vs Assignment Constructor 186

Chapter 33: Curiously Recurring Template Pattern (CRTP) 188

Introduction 188

Examples 188

The Curiously Recurring Template Pattern (CRTP) 188

CRTP to avoid code duplication 190

Chapter 34: Data Structures in C++ 192


Examples 192

Linked List implementation in C++ 192

Chapter 35: Date and time using header 195

Examples 195

Measuring time using 195

Find number of days between two dates 195

Chapter 36: decltype 197

Introduction 197

Examples 197

Basic Example 197

Another example 197

Chapter 37: Design pattern implementation in C++ 199

Introduction 199

Remarks 199

Examples 199

Observer pattern 199

Adapter Pattern 202

Factory Pattern 204

Builder Pattern with Fluent API 205

Pass the builder around 207

Design variant : Mutable object 207

Chapter 38: Digit separators 209

Examples 209

Digit Separator 209

Chapter 39: Enumeration 210

Examples 210

Basic Enumeration Declaration 210

Enumeration in switch statements 211

Iteration over an enum 211

Scoped enums 212

Enum forward declaration in C++11 213


Chapter 40: Exceptions 214

Examples 214

Catching exceptions 214

Rethrow (propagate) exception 215

Function Try Blocks In constructor 216

Function Try Block for regular function 216

Function Try Blocks In destructor 217

Best practice: throw by value, catch by const reference 217

Nested exception 218

std::uncaught_exceptions 220

Custom exception 221

Chapter 41: Explicit type conversions 224

Introduction 224

Syntax 224

Remarks 224

Examples 225

Base to derived conversion 225

Casting away constness 226

Type punning conversion 226

Conversion between pointer and integer 227

Conversion by explicit constructor or explicit conversion function 228

Implicit conversion 228

Enum conversions 229

Derived to base conversion for pointers to members 230

void* to T* 230

C-style casting 231

Chapter 42: Expression templates 232

Examples 232

Basic expression templates on element-wise algebraic expressions 232

File vec.hh : wrapper for std::vector, used to show log when a construction is called. 234

File expr.hh : implementation of expression templates for element-wise operations (vector 235

File main.cc : test src file 239


A basic example illustrating expression templates 241

Chapter 43: File I/O 246

Introduction 246

Examples 246

Opening a file 246

Reading from a file 247

Writing to a file 249

Opening modes 250

Closing a file 251

Flushing a stream 251

Reading an ASCII file into a std::string 252

Reading a file into a container 253

Reading a `struct` from a formatted text file. 254

Copying a file 255

Checking end of file inside a loop condition, bad practice? 255

Writing files with non-standard locale settings 256

Chapter 44: Floating Point Arithmetic 258

Examples 258

Floating Point Numbers are Weird 258

Chapter 45: Flow Control 260

Remarks 260

Examples 260

case 260

switch 260

catch 261

default 261

if 262

else 262

goto 262

return 263

throw 263

try 264
Conditional Structures: if, if..else 264

Jump statements : break, continue, goto, exit. 266

Chapter 46: Fold Expressions 270

Remarks 270

Examples 270

Unary Folds 270

Binary Folds 271

Folding over a comma 271

Chapter 47: Friend keyword 273

Introduction 273

Examples 273

Friend function 273

Friend method 274

Friend class 274

Chapter 48: Function Overloading 276

Introduction 276

Remarks 276

Examples 276

What is Function Overloading? 276

Return Type in Function Overloading 278

Member Function cv-qualifier Overloading 278

Chapter 49: Function Template Overloading 281

Remarks 281

Examples 281

What is a valid function template overloading? 281

Chapter 50: Futures and Promises 282

Introduction 282

Examples 282

std::future and std::promise 282

Deferred async example 282

std::packaged_task and std::future 283

std::future_error and std::future_errc 283


std::future and std::async 284

Async operation classes 286

Chapter 51: Header Files 287

Remarks 287

Examples 287

Basic Example 287

Source Files 287

The Compilation Process 288

Templates in Header Files 289

Chapter 52: Implementation-defined behavior 290

Examples 290

Char might be unsigned or signed 290

Size of integral types 290

Size of char 290

Size of signed and unsigned integer types 290

Size of char16_t and char32_t 292

Size of bool 292

Size of wchar_t 292

Data Models 293

Number of bits in a byte 293

Numeric value of a pointer 294

Ranges of numeric types 295

Value representation of floating point types 296

Overflow when converting from integer to signed integer 296

Underlying type (and hence size) of an enum 297

Chapter 53: Inline functions 298

Introduction 298

Syntax 298

Remarks 298

Inline as a linkage directive 298

FAQs 298
See Also 299

Examples 299

Non-member inline function declaration 299

Non-member inline function definition 299

Member inline functions 299

What is function inlining? 300

Chapter 54: Inline variables 301

Introduction 301

Examples 301

Defining a static data member in the class definition 301

Chapter 55: Internationalization in C++ 302

Remarks 302

Examples 302

Understanding C++ string characteristics 302

Chapter 56: Iteration 304

Examples 304

break 304

continue 304

do 304

for 304

while 305

range-based for loop 305

Chapter 57: Iterators 306

Examples 306

C Iterators (Pointers) 306

Breaking It Down 306

Overview 307

Iterators are Positions 307

From Iterators to Values 307

Invalid Iterators 309

Navigating with Iterators 309


Iterator Concepts 309

Iterator traits 310

Reverse Iterators 311

Vector Iterator 312

Map Iterator 312

Stream Iterators 313

Write your own generator-backed iterator 313

Chapter 58: Keywords 315

Introduction 315

Syntax 315

Remarks 315

Examples 317

asm 317

explicit 317

noexcept 318

typename 319

sizeof 320

Different keywords 321

Chapter 59: Lambdas 326

Syntax 326

Parameters 326

Remarks 326

Examples 327

What is a lambda expression? 327

Specifying the return type 330

Capture by value 330

Generalized capture 332

Capture by reference 333

Default capture 333

Generic lambdas 334

Conversion to function pointer 335

Class lambdas and capture of this 336


Porting lambda functions to C++03 using functors 337

Recursive lambdas 339

Use std::function 339

Using two smart pointers: 339

Use a Y-combinator 339

Using lambdas for inline parameter pack unpacking 340

Chapter 60: Layout of object types 343

Remarks 343

Examples 343

Class types 343

Arithmetic types 346

Narrow character types 346

Integer types 346

Floating point types 346

Arrays 346

Chapter 61: Linkage specifications 348

Introduction 348

Syntax 348

Remarks 348

Examples 348

Signal handler for Unix-like operating system 348

Making a C library header compatible with C++ 348

Chapter 62: Literals 350

Introduction 350

Examples 350

true 350

false 350

nullptr 350

this 351

Integer literal 351

Chapter 63: Loops 354

Introduction 354
Syntax 354

Remarks 354

Examples 354

Range-Based For 354

For loop 357

While loop 359

Declaration of variables in conditions 360

Do-while loop 361

Loop Control statements : Break and Continue 362

Range-for over a sub-range 363

Chapter 64: Memory management 365

Syntax 365

Remarks 365

Examples 365

Stack 365

Free Storage (Heap, Dynamic Allocation ...) 366

Placement new 367

Chapter 65: Metaprogramming 370

Introduction 370

Remarks 370

Examples 370

Calculating Factorials 370

Iterating over a parameter pack 372

Iterating with std::integer_sequence 374

Tag Dispatching 374

Detect Whether Expression is Valid 375

Calculating power with C++11 (and higher) 377

Manual distinction of types when given any type T 378

If-then-else 379

Generic Min/Max with variable argument count 379

Chapter 66: More undefined behaviors in C++ 380

Introduction 380
Examples 380

Referring to non-static members in initializer lists 380

Chapter 67: Move Semantics 381

Examples 381

Move semantics 381

Move constructor 381

Move assignment 383

Using std::move to reduce complexity from O(n²) to O(n) 384

Using move semantics on containers 387

Re-use a moved object 388

Chapter 68: mutable keyword 389

Examples 389

non-static class member modifier 389

mutable lambdas 389

Chapter 69: Mutexes 391

Remarks 391

It is better to use std::shared_mutex than std::shared_timed_mutex. 391

The code below is MSVC14.1 implementation of std::shared_mutex. 391

The code below is MSVC14.1 implementation of std::shared_timed_mutex. 393

std::shared_mutex processed read/write over 2 times more than std::shared_timed_mutex. 396

Examples 399

std::unique_lock, std::shared_lock, std::lock_guard 399

Strategies for lock classes: std::try_to_lock, std::adopt_lock, std::defer_lock 400

std::mutex 401

std::scoped_lock (C++ 17) 402

Mutex Types 402

std::lock 402

Chapter 70: Namespaces 403

Introduction 403

Syntax 403

Remarks 403

Examples 404
What are namespaces? 404

Making namespaces 405

Extending namespaces 406

Using directive 406

Argument Dependent Lookup 407

When does ADL not occur 407

Inline namespace 408

Unnamed/anonymous namespaces 410

Compact nested namespaces 410

Aliasing a long namespace 411

Alias Declaration scope 411

Namespace alias 412

Chapter 71: Non-Static Member Functions 413

Syntax 413

Remarks 413

Examples 413

Non-static Member Functions 413

Encapsulation 414

Name Hiding & Importing 415

Virtual Member Functions 417

Const Correctness 419

Chapter 72: One Definition Rule (ODR) 421

Examples 421

Multiply defined function 421

Inline functions 421

ODR violation via overload resolution 423

Chapter 73: Operator Overloading 424

Introduction 424

Remarks 424

Examples 424

Arithmetic operators 424

Unary operators 426


Comparison operators 427

Conversion operators 428

Array subscript operator 428

Function call operator 430

Assignment operator 430

Bitwise NOT operator 431

Bit shift operators for I/O 432

Complex Numbers Revisited 432

Named operators 437

Chapter 74: operator precedence 440

Remarks 440

Examples 440

Arithmetic operators 440

Logical AND and OR operators 441

Logical && and || operators: short-circuit 441

Unary Operators 442

Chapter 75: Optimization 444

Introduction 444

Examples 444

Inline Expansion/Inlining 444

Empty base optimization 444

Chapter 76: Optimization in C++ 446

Examples 446

Empty Base Class Optimization 446

Introduction to performance 446

Optimizing by executing less code 447

Removing useless code 447

Doing code only once 447

Preventing useless reallocating and copying/moving 448

Using efficient containers 448

Small Object Optimization 449

Example 449
When to use? 450

Chapter 77: Overload resolution 452

Remarks 452

Examples 452

Exact match 452

Categorization of argument to parameter cost 453

Name lookup and access checking 454

Overloading on Forwarding Reference 454

Steps of Overload Resolution 455

Arithmetic promotions and conversions 457

Overloading within a class hierarchy 458

Overloading on constness and volatility 459

Chapter 78: Parameter packs 461

Examples 461

A template with a parameter pack 461

Expansion of a parameter pack 461

Chapter 79: Perfect Forwarding 462

Remarks 462

Examples 462

Factory functions 462

Chapter 80: Pimpl Idiom 464

Remarks 464

Examples 464

Basic Pimpl idiom 464

Chapter 81: Pointers 466

Introduction 466

Syntax 466

Remarks 466

Examples 466

Pointer basics 466

Creating a pointer variable 466


Taking the address of another variable 467

Accessing the content of a pointer 468

Dereferencing invalid pointers 468

Pointer Operations 469

Pointer Arithmetic 469

Increment / Decrement 469

Addition / Subtraction 470

Pointer Differencing 470

Chapter 82: Pointers to members 472

Syntax 472

Examples 472

Pointers to static member functions 472

Pointers to member functions 473

Pointers to member variables 473

Pointers to static member variables 474

Chapter 83: Polymorphism 476

Examples 476

Define polymorphic classes 476

Safe downcasting 477

Polymorphism & Destructors 479

Chapter 84: Preprocessor 480

Introduction 480

Remarks 480

Examples 480

Include Guards 480

Conditional logic and cross-platform handling 481

Macros 483

Preprocessor error messages 486

Predefined macros 487

X-macros 489

#pragma once 490

Preprocessor Operators 491


Chapter 85: Profiling 493

Examples 493

Profiling with gcc and gprof 493

Generating callgraph diagrams with gperf2dot 494

Profiling CPU Usage with gcc and Google Perf Tools 495

Chapter 86: RAII: Resource Acquisition Is Initialization 498

Remarks 498

Examples 498

Locking 498

Finally/ScopeExit 499

ScopeSuccess (c++17) 500

ScopeFail (c++17) 501

Chapter 87: Random number generation 503

Remarks 503

Examples 503

True random value generator 503

Generating a pseudo-random number 504

Using the generator for multiple distributions 504

Chapter 88: Recursion in C++ 506

Examples 506

Using tail recursion and Fibonnaci-style recursion to solve the Fibonnaci sequence 506

Recursion with memoization 506

Chapter 89: Recursive Mutex 508

Examples 508

std::recursive_mutex 508

Chapter 90: Refactoring Techniques 509

Introduction 509

Examples 509

Refactoring walk through 509

Goto Cleanup 511

Chapter 91: References 513

Examples 513
Defining a reference 513

C++ References are Alias of existing variables 513

Chapter 92: Regular expressions 515

Introduction 515

Syntax 515

Parameters 515

Examples 516

Basic regex_match and regex_search Examples 516

regex_replace Example 516

regex_token_iterator Example 517

regex_iterator Example 517

Splitting a string 518

Quantifiers 518

Anchors 520

Chapter 93: Resource Management 521

Introduction 521

Examples 521

Resource Acquisition Is Initialization 521

Mutexes & Thread Safety 522

Chapter 94: Return Type Covariance 524

Remarks 524

Examples 524

1. Base example without covariant returns, shows why they're desirable 524

2. Covariant result version of the base example, static type checking. 525

3. Covariant smart pointer result (automated cleanup). 526

Chapter 95: Returning several values from a function 528

Introduction 528

Examples 528

Using Output Parameters 528

Using std::tuple 529

Using std::array 530

Using std::pair 530


Using struct 531

Structured Bindings 532

Using a Function Object Consumer 533

Using std::vector 534

Using Output Iterator 535

Chapter 96: RTTI: Run-Time Type Information 536

Examples 536

Name of a type 536

dynamic_cast 536

The typeid keyword 536

When to use which cast in c++ 537

Chapter 97: Scopes 538

Examples 538

Simple block scope 538

Global variables 538

Chapter 98: Semaphore 540

Introduction 540

Examples 540

Semaphore C++ 11 540

Semaphore class in action 540

Chapter 99: SFINAE (Substitution Failure Is Not An Error) 542

Examples 542

enable_if 542

When to use it 542

void_t 544

trailing decltype in function templates 545

What is SFINAE 546

enable_if_all / enable_if_any 547

is_detected 548

Overload resolution with a large number of options 550

Chapter 100: Side by Side Comparisons of classic C++ examples solved via C++ vs C++11 vs C
552
Examples 552

Looping through a container 552

Chapter 101: Singleton Design Pattern 554

Remarks 554

Examples 554

Lazy Initialization 554

Subclasses 555

Thread-safe Singeton 556

Static deinitialization-safe singleton. 556

Chapter 102: Smart Pointers 558

Syntax 558

Remarks 558

Examples 558

Sharing ownership (std::shared_ptr) 558

Sharing with temporary ownership (std::weak_ptr) 561

Unique ownership (std::unique_ptr) 562

Using custom deleters to create a wrapper to a C interface 565

Unique ownership without move semantics (auto_ptr) 566

Getting a shared_ptr referring to this 567

Casting std::shared_ptr pointers 568

Writing a smart pointer: value_ptr 569

Chapter 103: Sorting 572

Remarks 572

Examples 572

Sorting sequence containers with specifed ordering 572

Sorting sequence containers by overloaded less operator 572

Sorting sequence containers using compare function 573

Sorting sequence containers using lambda expressions (C++11) 574

Sorting and sequence containers 575

sorting with std::map (ascending and descending) 576

Sorting built-in arrays 578

Chapter 104: Special Member Functions 579


Examples 579

Virtual and Protected Destructors 579

Implicit Move and Copy 580

Copy and swap 580

Default Constructor 582

Destructor 584

Chapter 105: Standard Library Algorithms 587

Examples 587

std::for_each 587

std::next_permutation 587

std::accumulate 588

std::find 590

std::count 591

std::count_if 592

std::find_if 593

std::min_element 595

Using std::nth_element To Find The Median (Or Other Quantiles) 596

Chapter 106: static_assert 598

Syntax 598

Parameters 598

Remarks 598

Examples 598

static_assert 598

Chapter 107: std::any 600

Remarks 600

Examples 600

Basic usage 600

Chapter 108: std::array 601

Parameters 601

Remarks 601

Examples 601

Initializing an std::array 601


Element access 602

Checking size of the Array 604

Iterating through the Array 605

Changing all array elements at once 605

Chapter 109: std::atomics 606

Examples 606

atomic types 606

Chapter 110: std::forward_list 609

Introduction 609

Remarks 609

Examples 609

Example 609

Methods 610

Chapter 111: std::function: To wrap any element that is callable 612

Examples 612

Simple usage 612

std::function used with std::bind 612

std::function with lambda and std::bind 613

`function` overhead 614

Binding std::function to a different callable types 615

Storing function arguments in std::tuple 617

Chapter 112: std::integer_sequence 619

Introduction 619

Examples 619

Turn a std::tuple into function parameters 619

Create a parameter pack consisting of integers 620

Turn a sequence of indices into copies of an element 620

Chapter 113: std::iomanip 622

Examples 622

std::setw 622

std::setprecision 622

std::setfill 623
std::setiosflags 623

Chapter 114: std::map 625

Remarks 625

Examples 625

Accessing elements 625

Initializing a std::map or std::multimap 626

Deleting elements 627

Inserting elements 628

Iterating over std::map or std::multimap 629

Searching in std::map or in std::multimap 630

Checking number of elements 631

Types of Maps 631

Regular Map 631

Multi-Map 632

Hash-Map (Unordered Map) 632

Creating std::map with user-defined types as key 632

Strict Weak Ordering 632

Chapter 115: std::optional 634

Examples 634

Introduction 634

Other approaches to optional 634

Optional vs Pointer 634

Optional vs Sentinel 634

Optional vs std::pair<bool, T> 634

Using optionals to represent the absence of a value 634

Using optionals to represent the failure of a function 635

optional as return value 636

value_or 637

Chapter 116: std::pair 638

Examples 638

Creating a Pair and accessing the elements 638

Compare operators 638


Chapter 117: std::set and std::multiset 640

Introduction 640

Remarks 640

Examples 640

Inserting values in a set 640

Inserting values in a multiset 641

Changing the default sort of a set 642

Default sort 643

Custom sort 643

Lambda sort 644

Other sort options 644

Searching values in set and multiset 644

Deleting values from a set 645

Chapter 118: std::string 647

Introduction 647

Syntax 647

Remarks 648

Examples 648

Splitting 648

String replacement 649

Replace by position 649

Replace occurrences of a string with another string 649

Concatenation 650

Accessing a character 651

operator[](n) 651

at(n) 651

front() 651

back() 652

Tokenize 652

Conversion to (const) char* 653

Finding character(s) in a string 654


Trimming characters at start/end 654

Lexicographical comparison 656

Conversion to std::wstring 657

Using the std::string_view class 658

Looping through each character 659

Conversion to integers/floating point types 659

Converting between character encodings 660

Checking if a string is a prefix of another 661

Converting to std::string 662

Chapter 119: std::variant 664

Remarks 664

Examples 664

Basic std::variant use 664

Create pseudo-method pointers 665

Constructing a `std::variant` 666

Chapter 120: std::vector 667

Introduction 667

Remarks 667

Examples 667

Initializing a std::vector 667

Inserting Elements 668

Iterating Over std::vector 670

Iterating in the Forward Direction 670

Iterating in the Reverse Direction 670

Enforcing const elements 671

A Note on Efficiency 672

Accessing Elements 672

Index-based access: 672

Iterators: 675

Using std::vector as a C array 675

Iterator/Pointer Invalidation 676


Deleting Elements 677

Deleting the last element: 677

Deleting all elements: 677

Deleting element by index: 677

Deleting all elements in a range: 677

Deleting elements by value: 678

Deleting elements by condition: 678

Deleting elements by lambda, without creating additional predicate function 678

Deleting elements by condition from a loop: 678

Deleting elements by condition from a reverse loop: 679

Finding an Element in std::vector 680

Converting an array to std::vector 681

vector: The Exception To So Many, So Many Rules 682

Vector size and capacity 683

Concatenating Vectors 685

Reducing the Capacity of a Vector 685

Using a Sorted Vector for Fast Element Lookup 686

Functions Returning Large Vectors 687

Find max and min Element and Respective Index in a Vector 688

Matrices Using Vectors 689

Chapter 121: Storage class specifiers 691

Introduction 691

Remarks 691

Examples 691

mutable 691

register 692

static 692

auto 693

extern 693

Chapter 122: Stream manipulators 695

Introduction 695
Remarks 695

Examples 696

Stream manipulators 697

Output stream manipulators 703

Input stream manipulators 704

Chapter 123: Templates 706

Introduction 706

Syntax 706

Remarks 706

Examples 708

Function Templates 708

Argument forwarding 709

Basic Class Template 710

Template Specialization 711

Partial template specialization 711

Default template parameter value 713

Alias template 713

Template template parameters 714

Declaring non-type template arguments with auto 714

Empty custom deleter for unique_ptr 715

Non-type template parameter 715

Variadic template data structures 716

Explicit instantiation 719

Chapter 124: The ISO C++ Standard 721

Introduction 721

Remarks 721

Examples 722

Current Working Drafts 722

C++11 722

Language Extensions 722

General Features 722

Classes 723
Other Types 723

Templates 723

Concurrency 723

Miscellaneous Language Features 723

Library Extensions 723

General 724

Containers and Algorithms 724

Concurrency 724

C++14 724

Language Extensions 724

Library Extensions 725

Deprecated / Removed 725

C++17 725

Language Extensions 725

Library Extensions 726

C++03 726

Language Extensions 726

C++98 726

Language Extensions (in respect to C89/C90) 726

Library Extensions 726

C++20 727

Language Extensions 727

Library Extensions 727

Chapter 125: The Rule of Three, Five, And Zero 728

Examples 728

Rule of Five 728

Rule of Zero 729

Rule of Three 730

Self-assignment Protection 732

Chapter 126: The This Pointer 734

Remarks 734
Examples 734

this Pointer 734

Using the this Pointer to Access Member Data 736

Using the this Pointer to Differentiate Between Member Data and Parameters 737

this Pointer CV-Qualifiers 738

this Pointer Ref-Qualifiers 741

Chapter 127: Thread synchronization structures 743

Introduction 743

Examples 743

std::shared_lock 743

std::call_once, std::once_flag 743

Object locking for efficient access. 744

std::condition_variable_any, std::cv_status 745

Chapter 128: Threading 746

Syntax 746

Parameters 746

Remarks 746

Examples 746

Thread operations 746

Passing a reference to a thread 747

Creating a std::thread 747

Operations on the current thread 749

Using std::async instead of std::thread 751

Asynchronously calling a function 751

Common Pitfalls 751

Ensuring a thread is always joined 751

Reassigning thread objects 752

Basic Synchronization 753

Using Condition Variables 753

Create a simple thread pool 755

Thread-local storage 757

Chapter 129: Trailing return type 758


Syntax 758

Remarks 758

Examples 758

Avoid qualifying a nested type name 758

Lambda expressions 758

Chapter 130: type deduction 760

Remarks 760

Examples 760

Template parameter deduction for constructors 760

Template Type Deduction 760

Auto Type Deduction 761

Chapter 131: Type Erasure 764

Introduction 764

Examples 764

Basic mechanism 764

Erasing down to a Regular type with manual vtable 765

A move-only `std::function` 768

Erasing down to a contiguous buffer of T 770

Type erasing type erasure with std::any 772

Chapter 132: Type Inference 777

Introduction 777

Remarks 777

Examples 777

Data Type: Auto 777

Lambda auto 777

Loops and auto 778

Chapter 133: Type Keywords 779

Examples 779

class 779

struct 780

enum 780

union 781
Chapter 134: Type Traits 783

Remarks 783

Examples 783

Standard type traits 783

Constants 783

Functions 783

Types 784

Type relations with std::is_same 784

Fundamental type traits 785

Type Properties 786

Chapter 135: Typedef and type aliases 788

Introduction 788

Syntax 788

Examples 788

Basic typedef syntax 788

More complex uses of typedef 788

Declaring multiple types with typedef 789

Alias declaration with "using" 789

Chapter 136: Undefined Behavior 791

Introduction 791

Remarks 791

Examples 792

Reading or writing through a null pointer 792

No return statement for a function with a non-void return type 792

Modifying a string literal 793

Accessing an out-of-bounds index 793

Integer division by zero 794

Signed Integer Overflow 794

Using an uninitialized local variable 795

Multiple non-identical definitions (the One Definition Rule) 795

Incorrect pairing of memory allocation and deallocation 796

Accessing an object as the wrong type 797


Floating point overflow 797

Calling (Pure) Virtual Members From Constructor Or Destructor 798

Deleting a derived object via a pointer to a base class that doesn't have a virtual destru 798

Accessing a dangling reference 799

Extending the `std` or `posix` Namespace 799

Overflow during conversion to or from floating point type 800

Invalid base-to-derived static cast 800

Function call through mismatched function pointer type 801

Modifying a const object 801

Access to nonexistent member through pointer to member 802

Invalid derived-to-base conversion for pointers to members 802

Invalid pointer arithmetic 802

Shifting by an invalid number of positions 803

Returning from a [[noreturn]] function 803

Destroying an object that has already been destroyed 804

Infinite template recursion 804

Chapter 137: Unions 806

Remarks 806

Examples 806

Basic Union Features 806

Typical Use 806

Undefined Behavior 807

Chapter 138: Unit Testing in C++ 808

Introduction 808

Examples 808

Google Test 808

Minimal Example 808

Catch 808

Chapter 139: Unnamed types 810

Examples 810

Unnamed classes 810

Anonymous members 810


As a type alias 811

Anonymous Union 811

Chapter 140: Unspecified behavior 812

Remarks 812

Examples 812

Order of initialization of globals across TU 812

Value of an out-of-range enum 813

Static cast from bogus void* value 813

Result of some reinterpret_cast conversions 813

Result of some pointer comparisons 814

Space occupied by a reference 814

Evaluation order of function arguments 815

Moved-from state of most standard library classes 816

Chapter 141: User-Defined Literals 818

Examples 818

User-defined literals with long double values 818

Standard user-defined literals for duration 818

Standard user-defined literals for strings 819

Standard user-defined literals for complex 819

Self-made user-defined literal for binary 820

Chapter 142: Using declaration 822

Introduction 822

Syntax 822

Remarks 822

Examples 822

Importing names individually from a namespace 822

Redeclaring members from a base class to avoid name hiding 822

Inheriting constructors 823

Chapter 143: Using std::unordered_map 824

Introduction 824

Remarks 824

Examples 824
Declaration and Usage 824

Some Basic Functions 824

Chapter 144: Value and Reference Semantics 826

Examples 826

Deep copying and move support 826

Definitions 828

Chapter 145: Value Categories 830

Examples 830

Value Category Meanings 830

prvalue 830

xvalue 831

lvalue 831

glvalue 831

rvalue 832

Chapter 146: Variable Declaration Keywords 834

Examples 834

const 834

decltype 834

signed 835

unsigned 835

volatile 836

Chapter 147: Virtual Member Functions 837

Syntax 837

Remarks 837

Examples 837

Using override with virtual in C++11 and later 837

Virtual vs non-virtual member functions 838

Final virtual functions 839

Behaviour of virtual functions in constructors and destructors 840

Pure virtual functions 841

Credits 844
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: cplusplus

It is an unofficial and free C++ ebook created for educational purposes. All the content is extracted
from Stack Overflow Documentation, which is written by many hardworking individuals at Stack
Overflow. It is neither affiliated with Stack Overflow nor official C++.

The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/ 1
Chapter 1: Getting started with C++
Remarks
The 'Hello World' program is a common example that can be simply used to check compiler and
library presence. It uses the C++ standard library, with std::cout from <iostream>, and has only one
file to compile, minimizing the chance of possible user error during compilation.

The process for compiling a C++ program inherently differs between compilers and operating
systems. The topic Compiling and Building contains the details about how to compile C++ code on
different platforms for a variety of compilers.

Versions

Version Standard Release Date

C++98 ISO/IEC 14882:1998 1998-09-01

C++03 ISO/IEC 14882:2003 2003-10-16

C++11 ISO/IEC 14882:2011 2011-09-01

C++14 ISO/IEC 14882:2014 2014-12-15

C++17 TBD 2017-01-01

C++20 TBD 2020-01-01

Examples
Hello World

This program prints Hello World! to the standard output stream:

#include <iostream>

int main()
{
std::cout << "Hello World!" << std::endl;
}

See it live on Coliru.

https://riptutorial.com/ 2
Analysis
Let's examine each part of this code in detail:

• #include <iostream> is a preprocessor directive that includes the content of the standard
C++ header file iostream.

iostream is a standard library header file that contains definitions of the standard input and
output streams. These definitions are included in the std namespace, explained below.

The standard input/output (I/O) streams provide ways for programs to get input from and
output to an external system -- usually the terminal.

• int main() { ... }defines a new function named main. By convention, the main function is
called upon execution of the program. There must be only one main function in a C++
program, and it must always return a number of the int type.

Here, the int is what is called the function's return type. The value returned by the main
function is an exit code.

By convention, a program exit code of 0 or EXIT_SUCCESS is interpreted as success by a


system that executes the program. Any other return code is associated with an error.

If no return statement is present, the main function (and thus, the program itself) returns 0 by
default. In this example, we don't need to explicitly write return 0;.

All other functions, except those that return the void type, must explicitly return a value
according to their return type, or else must not return at all.

• std::cout << "Hello World!" << std::endl; prints "Hello World!" to the standard output
stream:

○ std is a namespace, and :: is the scope resolution operator that allows look-ups for
objects by name within a namespace.

There are many namespaces. Here, we use :: to show we want to use cout from the
std namespace. For more information refer to Scope Resolution Operator - Microsoft
Documentation.

○ std::coutis the standard output stream object, defined in iostream, and it prints to the
standard output (stdout).

○ <<is, in this context, the stream insertion operator, so called because it inserts an
object into the stream object.

The standard library defines the << operator to perform data insertion for certain data
types into output streams. stream << content inserts content into the stream and returns
the same, but updated stream. This allows stream insertions to be chained: std::cout
<< "Foo" << " Bar"; prints "FooBar" to the console.

https://riptutorial.com/ 3
○ "Hello World!" is a character string literal, or a "text literal." The stream insertion
operator for character string literals is defined in file iostream.

○ std::endl is a special I/O stream manipulator object, also defined in file iostream.
Inserting a manipulator into a stream changes the state of the stream.

The stream manipulator std::endl does two things: first it inserts the end-of-line
character and then it flushes the stream buffer to force the text to show up on the
console. This ensures that the data inserted into the stream actually appear on your
console. (Stream data is usually stored in a buffer and then "flushed" in batches unless
you force a flush immediately.)

An alternate method that avoids the flush is:

std::cout << "Hello World!\n";

where \n is the character escape sequence for the newline character.

○ The semicolon (;) notifies the compiler that a statement has ended. All C++ statements
and class definitions require an ending/terminating semicolon.

Comments

A comment is a way to put arbitrary text inside source code without having the C++ compiler
interpret it with any functional meaning. Comments are used to give insight into the design or
method of a program.

There are two types of comments in C++:

Single-Line Comments
The double forward-slash sequence // will mark all text until a newline as a comment:

int main()
{
// This is a single-line comment.
int a; // this also is a single-line comment
int i; // this is another single-line comment
}

C-Style/Block Comments
The sequence /* is used to declare the start of the comment block and the sequence */ is used to
declare the end of comment. All text between the start and end sequences is interpreted as a
comment, even if the text is otherwise valid C++ syntax. These are sometimes called "C-style"
comments, as this comment syntax is inherited from C++'s predecessor language, C:

https://riptutorial.com/ 4
int main()
{
/*
* This is a block comment.
*/
int a;
}

In any block comment, you can write anything you want. When the compiler encounters the
symbol */, it terminates the block comment:

int main()
{
/* A block comment with the symbol /*
Note that the compiler is not affected by the second /*
however, once the end-block-comment symbol is reached,
the comment ends.
*/
int a;
}

The above example is valid C++ (and C) code. However, having additional /* inside a block
comment might result in a warning on some compilers.

Block comments can also start and end within a single line. For example:

void SomeFunction(/* argument 1 */ int a, /* argument 2 */ int b);

Importance of Comments
As with all programming languages, comments provide several benefits:

• Explicit documentation of code to make it easier to read/maintain


• Explanation of the purpose and functionality of code
• Details on the history or reasoning behind the code
• Placement of copyright/licenses, project notes, special thanks, contributor credits, etc.
directly in the source code.

However, comments also have their downsides:

• They must be maintained to reflect any changes in the code


• Excessive comments tend to make the code less readable

The need for comments can be reduced by writing clear, self-documenting code. A simple
example is the use of explanatory names for variables, functions, and types. Factoring out logically
related tasks into discrete functions goes hand-in-hand with this.

Comment markers used to disable code

https://riptutorial.com/ 5
During development, comments can also be used to quickly disable portions of code without
deleting it. This is often useful for testing or debugging purposes, but is not good style for anything
other than temporary edits. This is often referred to as “commenting out”.

Similarly, keeping old versions of a piece of code in a comment for reference purposes is frowned
upon, as it clutters files while offering little value compared to exploring the code's history via a
versioning system.

Function

A function is a unit of code that represents a sequence of statements.

Functions can accept arguments or values and return a single value (or not). To use a function, a
function call is used on argument values and the use of the function call itself is replaced with its
return value.

Every function has a type signature -- the types of its arguments and the type of its return type.

Functions are inspired by the concepts of the procedure and the mathematical function.

• Note: C++ functions are essentially procedures and do not follow the exact definition or rules
of mathematical functions.

Functions are often meant to perform a specific task. and can be called from other parts of a
program. A function must be declared and defined before it is called elsewhere in a program.

• Note: popular function definitions may be hidden in other included files (often for
convenience and reuse across many files). This is a common use of header files.

Function Declaration
A function declaration is declares the existence of a function with its name and type signature to
the compiler. The syntax is as the following:

int add2(int i); // The function is of the type (int) -> (int)

In the example above, the int add2(int i) function declares the following to the compiler:

• The return type is int.


• The name of the function is add2.
• The number of arguments to the function is 1:
The first argument is of the type int.

The first argument will be referred to in the function's contents by the name i.

The argument name is optional; the declaration for the function could also be the following:

int add2(int); // Omitting the function arguments' name is also permitted.

https://riptutorial.com/ 6
Per the one-definition rule, a function with a certain type signature can only be declared or
defined once in an entire C++ code base visible to the C++ compiler. In other words, functions with
a specific type signature cannot be re-defined -- they must only be defined once. Thus, the
following is not valid C++:

int add2(int i); // The compiler will note that add2 is a function (int) -> int
int add2(int j); // As add2 already has a definition of (int) -> int, the compiler
// will regard this as an error.

If a function returns nothing, its return type is written as void. If it takes no parameters, the
parameter list should be empty.

void do_something(); // The function takes no parameters, and does not return anything.
// Note that it can still affect variables it has access to.

Function Call
A function can be called after it has been declared. For example, the following program calls add2
with the value of 2 within the function of main:

#include <iostream>

int add2(int i); // Declaration of add2

// Note: add2 is still missing a DEFINITION.


// Even though it doesn't appear directly in code,
// add2's definition may be LINKED in from another object file.

int main()
{
std::cout << add2(2) << "\n"; // add2(2) will be evaluated at this point,
// and the result is printed.
return 0;
}

Here, add2(2) is the syntax for a function call.

Function Definition
A function definition* is similar to a declaration, except it also contains the code that is executed
when the function is called within its body.

An example of a function definition for add2 might be:

int add2(int i) // Data that is passed into (int i) will be referred to by the name i
{ // while in the function's curly brackets or "scope."

int j = i + 2; // Definition of a variable j as the value of i+2.


return j; // Returning or, in essence, substitution of j for a function call to

https://riptutorial.com/ 7
// add2.
}

Function Overloading
You can create multiple functions with the same name but different parameters.

int add2(int i) // Code contained in this definition will be evaluated


{ // when add2() is called with one parameter.
int j = i + 2;
return j;
}

int add2(int i, int j) // However, when add2() is called with two parameters, the
{ // code from the initial declaration will be overloaded,
int k = i + j + 2 ; // and the code in this declaration will be evaluated
return k; // instead.
}

Both functions are called by the same name add2, but the actual function that is called depends
directly on the amount and type of the parameters in the call. In most cases, the C++ compiler can
compute which function to call. In some cases, the type must be explicitly stated.

Default Parameters
Default values for function parameters can only be specified in function declarations.

int multiply(int a, int b = 7); // b has default value of 7.


int multiply(int a, int b)
{
return a * b; // If multiply() is called with one parameter, the
} // value will be multiplied by the default, 7.

In this example, multiply() can be called with one or two parameters. If only one parameter is
given, b will have default value of 7. Default arguments must be placed in the latter arguments of
the function. For example:

int multiply(int a = 10, int b = 20); // This is legal


int multiply(int a = 10, int b); // This is illegal since int a is in the former

Special Function Calls - Operators


There exist special function calls in C++ which have different syntax than name_of_function(value1,
value2, value3). The most common example is that of operators.

Certain special character sequences that will be reduced to function calls by the compiler, such as
!, +, -, *, %, and << and many more. These special characters are normally associated with non-

https://riptutorial.com/ 8
programming usage or are used for aesthetics (e.g. the + character is commonly recognized as the
addition symbol both within C++ programming as well as in elementary math).

C++ handles these character sequences with a special syntax; but, in essence, each occurrence
of an operator is reduced to a function call. For example, the following C++ expression:

3+3

is equivalent to the following function call:

operator+(3, 3)

All operator function names start with operator.

While in C++'s immediate predecessor, C, operator function names cannot be assigned different
meanings by providing additional definitions with different type signatures, in C++, this is valid.
"Hiding" additional function definitions under one unique function name is referred to as operator
overloading in C++, and is a relatively common, but not universal, convention in C++.

Visibility of function prototypes and declarations

In C++, code must be declared or defined before usage. For example, the following produces a
compile time error:

int main()
{
foo(2); // error: foo is called, but has not yet been declared
}

void foo(int x) // this later definition is not known in main


{
}

There are two ways to resolve this: putting either the definition or declaration of foo() before its
usage in main(). Here is one example:

void foo(int x) {} //Declare the foo function and body first

int main()
{
foo(2); // OK: foo is completely defined beforehand, so it can be called here.
}

However it is also possible to "forward-declare" the function by putting only a "prototype"


declaration before its usage and then defining the function body later:

void foo(int); // Prototype declaration of foo, seen by main


// Must specify return type, name, and argument list types
int main()
{
foo(2); // OK: foo is known, called even though its body is not yet defined

https://riptutorial.com/ 9
}

void foo(int x) //Must match the prototype


{
// Define body of foo here
}

The prototype must specify the return type (void), the name of the function (foo), and the argument
list variable types (int), but the names of the arguments are NOT required.

One common way to integrate this into the organization of source files is to make a header file
containing all of the prototype declarations:

// foo.h
void foo(int); // prototype declaration

and then provide the full definition elsewhere:

// foo.cpp --> foo.o


#include "foo.h" // foo's prototype declaration is "hidden" in here
void foo(int x) { } // foo's body definition

and then, once compiled, link the corresponding object file foo.o into the compiled object file
where it is used in the linking phase, main.o:

// main.cpp --> main.o


#include "foo.h" // foo's prototype declaration is "hidden" in here
int main() { foo(2); } // foo is valid to call because its prototype declaration was
beforehand.
// the prototype and body definitions of foo are linked through the object files

An “unresolved external symbol” error occurs when the function prototype and call exist, but the
function body is not defined. These can be trickier to resolve as the compiler won't report the error
until the final linking stage, and it doesn't know which line to jump to in the code to show the error.

The standard C++ compilation process

Executable C++ program code is usually produced by a compiler.

A compiler is a program that translates code from a programming language into another form
which is (more) directly executable for a computer. Using a compiler to translate code is called
compilation.

C++ inherits the form of its compilation process from its "parent" language, C. Below is a list
showing the four major steps of compilation in C++:

1. The C++ preprocessor copies the contents of any included header files into the source code
file, generates macro code, and replaces symbolic constants defined using #define with their
values.
2. The expanded source code file produced by the C++ preprocessor is compiled into assembly

https://riptutorial.com/ 10
language appropriate for the platform.
3. The assembler code generated by the compiler is assembled into appropriate object code for
the platform.
4. The object code file generated by the assembler is linked together with the object code files
for any library functions used to produce an executable file.

• Note: some compiled code is linked together, but not to create a final program. Usually, this
"linked" code can also be packaged into a format that can be used by other programs. This
"bundle of packaged, usable code" is what C++ programmers refer to as a library.

Many C++ compilers may also merge or un-merge certain parts of the compilation process for
ease or for additional analysis. Many C++ programmers will use different tools, but all of the tools
will generally follow this generalized process when they are involved in the production of a
program.

The link below extends this discussion and provides a nice graphic to help. [1]:
http://faculty.cs.niu.edu/~mcmahon/CS241/Notes/compile.html

Preprocessor

The preprocessor is an important part of the compiler.

It edits the source code, cutting some bits out, changing others, and adding other things.

In source files, we can include preprocessor directives. These directives tells the preprocessor to
perform specific actions. A directive starts with a # on a new line. Example:

#define ZERO 0

The first preprocessor directive you will meet is probably the

#include <something>

directive. What it does is takes all of something and inserts it in your file where the directive was.
The hello world program starts with the line

#include <iostream>

This line adds the functions and objects that let you use the standard input and output.

The C language, which also uses the preprocessor, does not have as many header files as the
C++ language, but in C++ you can use all the C header files.

The next important directive is probably the

#define something something_else

https://riptutorial.com/ 11
directive. This tells the preprocessor that as it goes along the file, it should replace every
occurrence of something with something_else. It can also make things similar to functions, but that
probably counts as advanced C++.

The something_else is not needed, but if you define something as nothing, then outside preprocessor
directives, all occurrences of something will vanish.

This actually is useful, because of the #if,#else and #ifdef directives. The format for these would
be the following:

#if something==true
//code
#else
//more code
#endif

#ifdef thing_that_you_want_to_know_if_is_defined
//code
#endif

These directives insert the code that is in the true bit, and deletes the false bits. this can be used
to have bits of code that are only included on certain operating systems, without having to rewrite
the whole code.

Read Getting started with C++ online: https://riptutorial.com/cplusplus/topic/206/getting-started-


with-cplusplus

https://riptutorial.com/ 12
Chapter 2: Alignment
Introduction
All types in C++ have an alignment. This is a restriction on the memory address that objects of that
type can be created within. A memory address is valid for an object's creation if dividing that
address by the object's alignment is a whole number.

Type alignments are always a power of two (including 1).

Remarks
The standard guarantees the following:

• The alignment requirement of a type is a divisor of its size. For example, a class with size 16
bytes could have an alignment of 1, 2, 4, 8, or 16, but not 32. (If a class's members only total
14 bytes in size, but the class needs to have an alignment requirement of 8, the compiler will
insert 2 padding bytes to make the class's size equal to 16.)

• The signed and unsigned versions of an integer type have the same alignment requirement.
• A pointer to void has the same alignment requirement as a pointer to char.
• The cv-qualified and cv-unqualified versions of a type have the same alignment requirement.

Note that while alignment exists in C++03, it was not until C++11 that it became possible to query
alignment (using alignof) and control alignment (using alignas).

Examples
Querying the alignment of a type

c++11

The alignment requirement of a type can be queried using the alignof keyword as a unary
operator. The result is a constant expression of type std::size_t, i.e., it can be evaluated at
compile time.

#include <iostream>
int main() {
std::cout << "The alignment requirement of int is: " << alignof(int) << '\n';
}

Possible output

The alignment requirement of int is: 4

If applied to an array, it yields the alignment requirement of the element type. If applied to a

https://riptutorial.com/ 13
reference type, it yields the alignment requirement of the referenced type. (References themselves
have no alignment, since they are not objects.)

Controlling alignment

C++11

The alignas keyword can be used to force a variable, class data member, declaration or definition
of a class, or declaration or definition of an enum, to have a particular alignment, if supported. It
comes in two forms:

• alignas(x), where x is a constant expression, gives the entity the alignment x, if supported.
• alignas(T), where T is a type, gives the entity an alignment equal to the alignment
requirement of T, that is, alignof(T), if supported.

If multiple alignas specifiers are applied to the same entity, the strictest one applies.

In this example, the buffer buf is guaranteed to be appropriately aligned to hold an int object, even
though its element type is unsigned char, which may have a weaker alignment requirement.

alignas(int) unsigned char buf[sizeof(int)];


new (buf) int(42);

alignas cannot be used to give a type a smaller alignment than the type would have without this
declaration:

alignas(1) int i; //Il-formed, unless `int` on this platform is aligned to 1 byte.


alignas(char) int j; //Il-formed, unless `int` has the same or smaller alignment than `char`.

alignas, when given an integer constant expression, must be given a valid alignment. Valid
alignments are always powers of two, and must be greater than zero. Compilers are required to
support all valid alignments up to the alignment of the type std::max_align_t. They may support
larger alignments than this, but support for allocating memory for such objects is limited. The
upper limit on alignments is implementation dependent.

C++17 features direct support in operator new for allocating memory for over-aligned types.

Read Alignment online: https://riptutorial.com/cplusplus/topic/9249/alignment

https://riptutorial.com/ 14
Chapter 3: Argument Dependent Name
Lookup
Examples
What functions are found

Functions are found by first collecting a set of "associated classes" and "associated namespaces"
that include one ore more of the following, depending on the argument type T. First, let us show
the rules for classes, enumeration and class template specialization names.

• If T is a nested class, member enumeration, then the surrounding class of it.


• If T is an enumeration (it may also be a class member!), the innermost namespace of it.
• If T is a class (it may also be nested!), all its base classes and the class itself. The innermost
namespace of all associated classes.
• If T is a ClassTemplate<TemplateArguments> (this is also a class!), the classes and namespaces
associated with the template type arguments, the namespace of any template template
argument and the surrounding class of any template template argument, if a template
argument is a member template.

Now there are a few rules for builtin types as well

• If T is a pointer to U or array of U, the classes and namespaces associated with U. Example:


void (*fptr)(A); f(fptr);, includes the namespaces and classes associated with void(A)
(see next rule).
• If T is a function type, the classes and namespaces associated with parameter and return
types. Example: void(A) would includes the namespaces and classes associated with A.
• If T is a pointer to member, the classes and namespaces associated with the member type
(may apply to both pointer to member functions and pointer to data member!). Example: B
A::*p; void (A::*pf)(B); f(p); f(pf); includes the namespaces and classes associated with
A, B, void(B) (which applies bullet above for function types).

All functions and templates within all associated namespaces are found by argument dependent
lookup. In addition, namespace-scope friend functions declared in associated classes are found,
which are normally not visible. Using directives are ignored, however.

All of the following example calls are valid, without qualifying f by the namespace name in the call.

namespace A {
struct Z { };
namespace I { void g(Z); }
using namespace I;

struct X { struct Y { }; friend void f(Y) { } };


void f(X p) { }
void f(std::shared_ptr<X> p) { }
}

https://riptutorial.com/ 15
// example calls
f(A::X());
f(A::X::Y());
f(std::make_shared<A::X>());

g(A::Z()); // invalid: "using namespace I;" is ignored!

Read Argument Dependent Name Lookup online:


https://riptutorial.com/cplusplus/topic/5163/argument-dependent-name-lookup

https://riptutorial.com/ 16
Chapter 4: Arithmitic Metaprogramming
Introduction
These are example of using C++ template metaprogramming in processing arithmitic operations in
compile time.

Examples
Calculating power in O(log n)

This example shows an efficient way of calculating power using template metaprogramming.

template <int base, unsigned int exponent>


struct power
{
static const int halfvalue = power<base, exponent / 2>::value;
static const int value = halfvalue * halfvalue * power<base, exponent % 2>::value;
};

template <int base>


struct power<base, 0>
{
static const int value = 1;
static_assert(base != 0, "power<0, 0> is not allowed");
};

template <int base>


struct power<base, 1>
{
static const int value = base;
};

Example Usage:

std::cout << power<2, 9>::value;

C++14

This one also handles negative exponents:

template <int base, int exponent>


struct powerDouble
{
static const int exponentAbs = exponent < 0 ? (-exponent) : exponent;
static const int halfvalue = powerDouble<base, exponentAbs / 2>::intermediateValue;
static const int intermediateValue = halfvalue * halfvalue * powerDouble<base, exponentAbs
% 2>::intermediateValue;

constexpr static double value = exponent < 0 ? (1.0 / intermediateValue) :

https://riptutorial.com/ 17
intermediateValue;

};

template <int base>


struct powerDouble<base, 0>
{
static const int intermediateValue = 1;
constexpr static double value = 1;
static_assert(base != 0, "powerDouble<0, 0> is not allowed");
};

template <int base>


struct powerDouble<base, 1>
{
static const int intermediateValue = base;
constexpr static double value = base;
};

int main()
{
std::cout << powerDouble<2,-3>::value;
}

Read Arithmitic Metaprogramming online: https://riptutorial.com/cplusplus/topic/10907/arithmitic-


metaprogramming

https://riptutorial.com/ 18
Chapter 5: Arrays
Introduction
Arrays are elements of the same type placed in adjoining memory locations. The elements can be
individually referenced by a unique identifier with an added index.

This allows you to declare multiple variable values of a specific type and access them individually
without needing to declare a variable for each value.

Examples
Array size: type safe at compile time.

#include <stddef.h> // size_t, ptrdiff_t

//----------------------------------- Machinery:

using Size = ptrdiff_t;

template< class Item, size_t n >


constexpr auto n_items( Item (&)[n] ) noexcept
-> Size
{ return n; }

//----------------------------------- Usage:

#include <iostream>
using namespace std;
auto main()
-> int
{
int const a[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4};
Size const n = n_items( a );
int b[n] = {}; // An array of the same size as a.

(void) b;
cout << "Size = " << n << "\n";
}

The C idiom for array size, sizeof(a)/sizeof(a[0]), will accept a pointer as argument and will then
generally yield an incorrect result.

For C++11

using C++11 you can do:

std::extent<decltype(MyArray)>::value;

Example:

https://riptutorial.com/ 19
char MyArray[] = { 'X','o','c','e' };
const auto n = std::extent<decltype(MyArray)>::value;
std::cout << n << "\n"; // Prints 4

Up till C++17 (forthcoming as of this writing) C++ had no built-in core language or standard library
utility to obtain the size of an array, but this can be implemented by passing the array by reference
to a function template, as shown above. Fine but important point: the template size parameter is a
size_t, somewhat inconsistent with the signed Size function result type, in order to accommodate
the g++ compiler which sometimes insists on size_t for template matching.

With C++17 and later one may instead use std::size, which is specialized for arrays.

Dynamically sized raw array

// Example of raw dynamic size array. It's generally better to use std::vector.
#include <algorithm> // std::sort
#include <iostream>
using namespace std;

auto int_from( istream& in ) -> int { int x; in >> x; return x; }

auto main()
-> int
{
cout << "Sorting n integers provided by you.\n";
cout << "n? ";
int const n = int_from( cin );
int* a = new int[n]; // ← Allocation of array of n items.

for( int i = 1; i <= n; ++i )


{
cout << "The #" << i << " number, please: ";
a[i-1] = int_from( cin );
}

sort( a, a + n );
for( int i = 0; i < n; ++i ) { cout << a[i] << ' '; }
cout << '\n';

delete[] a;
}

A program that declares an array T a[n]; where n is determined a run-time, can compile with
certain compilers that support C99 variadic length arrays (VLAs) as a language extension. But
VLAs are not supported by standard C++. This example shows how to manually allocate a
dynamic size array via a new[]-expression,

int* a = new int[n]; // ← Allocation of array of n items.

… then use it, and finally deallocate it via a delete[]-expression:

delete[] a;

https://riptutorial.com/ 20
The array allocated here has indeterminate values, but it can be zero-initialized by just adding an
empty parenthesis (), like this: new int[n](). More generally, for arbitrary item type, this performs a
value-initialization.

As part of a function down in a call hierarchy this code would not be exception safe, since an
exception before the delete[] expression (and after the new[]) would cause a memory leak. One
way to address that issue is to automate the cleanup via e.g. a std::unique_ptr smart pointer. But
a generally better way to address it is to just use a std::vector: that's what std::vector is there for.

Expanding dynamic size array by using std::vector.

// Example of std::vector as an expanding dynamic size array.


#include <algorithm> // std::sort
#include <iostream>
#include <vector> // std::vector
using namespace std;

int int_from( std::istream& in ) { int x = 0; in >> x; return x; }

int main()
{
cout << "Sorting integers provided by you.\n";
cout << "You can indicate EOF via F6 in Windows or Ctrl+D in Unix-land.\n";
vector<int> a; // ← Zero size by default.

while( cin )
{
cout << "One number, please, or indicate EOF: ";
int const x = int_from( cin );
if( !cin.fail() ) { a.push_back( x ); } // Expands as necessary.
}

sort( a.begin(), a.end() );


int const n = a.size();
for( int i = 0; i < n; ++i ) { cout << a[i] << ' '; }
cout << '\n';
}

std::vector is a standard library class template that provides the notion of a variable size array. It
takes care of all the memory management, and the buffer is contiguous so a pointer to the buffer
(e.g. &v[0] or v.data()) can be passed to API functions requiring a raw array. A vector can even be
expanded at run time, via e.g. the push_back member function that appends an item.

The complexity of the sequence of n push_back operations, including the copying or moving
involved in the vector expansions, is amortized O(n). “Amortized”: on average.

Internally this is usually achieved by the vector doubling its buffer size, its capacity, when a larger
buffer is needed. E.g. for a buffer starting out as size 1, and being repeatedly doubled as needed
for n=17 push_back calls, this involves 1 + 2 + 4 + 8 + 16 = 31 copy operations, which is less than
2×n = 34. And more generally the sum of this sequence can't exceed 2×n.

Compared to the dynamic size raw array example, this vector-based code does not require the
user to supply (and know) the number of items up front. Instead the vector is just expanded as

https://riptutorial.com/ 21
necessary, for each new item value specified by the user.

A fixed size raw array matrix (that is, a 2D raw array).

// A fixed size raw array matrix (that is, a 2D raw array).


#include <iostream>
#include <iomanip>
using namespace std;

auto main() -> int


{
int const n_rows = 3;
int const n_cols = 7;
int const m[n_rows][n_cols] = // A raw array matrix.
{
{ 1, 2, 3, 4, 5, 6, 7 },
{ 8, 9, 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19, 20, 21 }
};

for( int y = 0; y < n_rows; ++y )


{
for( int x = 0; x < n_cols; ++x )
{
cout << setw( 4 ) << m[y][x]; // Note: do NOT use m[y,x]!
}
cout << '\n';
}
}

Output:

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21

C++ doesn't support special syntax for indexing a multi-dimensional array. Instead such an array
is viewed as an array of arrays (possibly of arrays, and so on), and the ordinary single index
notation [i] is used for each level. In the example above m[y] refers to row y of m, where y is a
zero-based index. Then this row can be indexed in turn, e.g. m[y][x], which refers to the xth item –
or column – of row y.

I.e. the last index varies fastest, and in the declaration the range of this index, which here is the
number of columns per row, is the last and “innermost” size specified.

Since C++ doesn't provide built-in support for dynamic size arrays, other than dynamic allocation,
a dynamic size matrix is often implemented as a class. Then the raw array matrix indexing
notation m[y][x] has some cost, either by exposing the implementation (so that e.g. a view of a
transposed matrix becomes practically impossible) or by adding some overhead and slight
inconvenience when it's done by returning a proxy object from operator[]. And so the indexing
notation for such an abstraction can and will usually be different, both in look-and-feel and in the
order of indices, e.g. m(x,y) or m.at(x,y) or m.item(x,y).

https://riptutorial.com/ 22
A dynamic size matrix using std::vector for storage.

Unfortunately as of C++14 there's no dynamic size matrix class in the C++ standard library. Matrix
classes that support dynamic size are however available from a number of 3rd party libraries,
including the Boost Matrix library (a sub-library within the Boost library).

If you don't want a dependency on Boost or some other library, then one poor man's dynamic size
matrix in C++ is just like

vector<vector<int>> m( 3, vector<int>( 7 ) );

… where vector is std::vector. The matrix is here created by copying a row vector n times where n
is the number of rows, here 3. It has the advantage of providing the same m[y][x] indexing
notation as for a fixed size raw array matrix, but it's a bit inefficient because it involves a dynamic
allocation for each row, and it's a bit unsafe because it's possible to inadvertently resize a row.

A more safe and efficient approach is to use a single vector as storage for the matrix, and map the
client code's (x, y) to a corresponding index in that vector:

// A dynamic size matrix using std::vector for storage.

//--------------------------------------------- Machinery:
#include <algorithm> // std::copy
#include <assert.h> // assert
#include <initializer_list> // std::initializer_list
#include <vector> // std::vector
#include <stddef.h> // ptrdiff_t

namespace my {
using Size = ptrdiff_t;
using std::initializer_list;
using std::vector;

template< class Item >


class Matrix
{
private:
vector<Item> items_;
Size n_cols_;

auto index_for( Size const x, Size const y ) const


-> Size
{ return y*n_cols_ + x; }

public:
auto n_rows() const -> Size { return items_.size()/n_cols_; }
auto n_cols() const -> Size { return n_cols_; }

auto item( Size const x, Size const y )


-> Item&
{ return items_[index_for(x, y)]; }

auto item( Size const x, Size const y ) const


-> Item const&
{ return items_[index_for(x, y)]; }

https://riptutorial.com/ 23
Matrix(): n_cols_( 0 ) {}

Matrix( Size const n_cols, Size const n_rows )


: items_( n_cols*n_rows )
, n_cols_( n_cols )
{}

Matrix( initializer_list< initializer_list<Item> > const& values )


: items_()
, n_cols_( values.size() == 0? 0 : values.begin()->size() )
{
for( auto const& row : values )
{
assert( Size( row.size() ) == n_cols_ );
items_.insert( items_.end(), row.begin(), row.end() );
}
}
};
} // namespace my

//--------------------------------------------- Usage:
using my::Matrix;

auto some_matrix()
-> Matrix<int>
{
return
{
{ 1, 2, 3, 4, 5, 6, 7 },
{ 8, 9, 10, 11, 12, 13, 14 },
{ 15, 16, 17, 18, 19, 20, 21 }
};
}

#include <iostream>
#include <iomanip>
using namespace std;
auto main() -> int
{
Matrix<int> const m = some_matrix();
assert( m.n_cols() == 7 );
assert( m.n_rows() == 3 );
for( int y = 0, y_end = m.n_rows(); y < y_end; ++y )
{
for( int x = 0, x_end = m.n_cols(); x < x_end; ++x )
{
cout << setw( 4 ) << m.item( x, y ); // ← Note: not `m[y][x]`!
}
cout << '\n';
}
}

Output:

1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21

https://riptutorial.com/ 24
The above code is not industrial grade: it's designed to show the basic principles, and serve the
needs of students learning C++.

For example, one may define operator() overloads to simplify the indexing notation.

Array initialization

An array is just a block of sequential memory locations for a specific type of variable. Arrays are
allocated the same way as normal variables, but with square brackets appended to its name []
that contain the number of elements that fit into the array memory.

The following example of an array uses the typ int, the variable name arrayOfInts, and the
number of elements [5] that the array has space for:

int arrayOfInts[5];

An array can be declared and initialized at the same time like this

int arrayOfInts[5] = {10, 20, 30, 40, 50};

When initializing an array by listing all of its members, it is not necessary to include the number of
elements inside the square brackets. It will be automatically calculated by the compiler. In the
following example, it's 5:

int arrayOfInts[] = {10, 20, 30, 40, 50};

It is also possible to initialize only the first elements while allocating more space. In this case,
defining the length in brackets is mandatory. The following will allocate an array of length 5 with
partial initialization, the compiler initializes all remaining elements with the standard value of the
element type, in this case zero.

int arrayOfInts[5] = {10,20}; // means 10, 20, 0, 0, 0

Arrays of other basic data types may be initialized in the same way.

char arrayOfChars[5]; // declare the array and allocate the memory, don't initialize

char arrayOfChars[5] = { 'a', 'b', 'c', 'd', 'e' } ; //declare and initialize

double arrayOfDoubles[5] = {1.14159, 2.14159, 3.14159, 4.14159, 5.14159};

string arrayOfStrings[5] = { "C++", "is", "super", "duper", "great!"};

It is also important to take note that when accessing array elements, the array's element index(or
position) starts from 0.

int array[5] = { 10/*Element no.0*/, 20/*Element no.1*/, 30, 40, 50/*Element no.4*/};
std::cout << array[4]; //outputs 50
std::cout << array[0]; //outputs 10

https://riptutorial.com/ 25
Read Arrays online: https://riptutorial.com/cplusplus/topic/3017/arrays

https://riptutorial.com/ 26
Chapter 6: Atomic Types
Syntax
• std::atomic<T>
• std::atomic_flag

Remarks
std::atomic allows atomic access to a TriviallyCopyable type, it is implementation-dependent if this
is done via atomic operations or by using locks. The only guaranteed lock-free atomic type is
std::atomic_flag.

Examples
Multi-threaded Access

An atomic type can be used to safely read and write to a memory location shared between two
threads.

A Bad example that is likely to cause a data race:

#include <thread>
#include <iostream>

//function will add all values including and between 'a' and 'b' to 'result'
void add(int a, int b, int * result) {
for (int i = a; i <= b; i++) {
*result += i;
}
}

int main() {
//a primitive data type has no thread safety
int shared = 0;

//create a thread that may run parallel to the 'main' thread


//the thread will run the function 'add' defined above with paramters a = 1, b = 100,
result = &shared
//analogous to 'add(1,100, &shared);'
std::thread addingThread(add, 1, 100, &shared);

//attempt to print the value of 'shared' to console


//main will keep repeating this until the addingThread becomes joinable
while (!addingThread.joinable()) {
//this may cause undefined behavior or print a corrupted value
//if the addingThread tries to write to 'shared' while the main thread is reading it
std::cout << shared << std::endl;
}

https://riptutorial.com/ 27
//rejoin the thread at the end of execution for cleaning purposes
addingThread.join();

return 0;
}

The above example may cause a corrupted read and can lead to undefined behavior.

An example with thread safety:

#include <atomic>
#include <thread>
#include <iostream>

//function will add all values including and between 'a' and 'b' to 'result'
void add(int a, int b, std::atomic<int> * result) {
for (int i = a; i <= b; i++) {
//atomically add 'i' to result
result->fetch_add(i);
}
}

int main() {
//atomic template used to store non-atomic objects
std::atomic<int> shared = 0;

//create a thread that may run parallel to the 'main' thread


//the thread will run the function 'add' defined above with paramters a = 1, b = 100,
result = &shared
//analogous to 'add(1,100, &shared);'
std::thread addingThread(add, 1, 10000, &shared);

//print the value of 'shared' to console


//main will keep repeating this until the addingThread becomes joinable
while (!addingThread.joinable()) {
//safe way to read the value of shared atomically for thread safe read
std::cout << shared.load() << std::endl;
}

//rejoin the thread at the end of execution for cleaning purposes


addingThread.join();

return 0;
}

The above example is safe because all store() and load() operations of the atomic data type
protect the encapsulated int from simultaneous access.

Read Atomic Types online: https://riptutorial.com/cplusplus/topic/3804/atomic-types

https://riptutorial.com/ 28
Chapter 7: Attributes
Syntax
• [[details]]: Simple no-argument attribute

• [[details(arguments)]]: Attribute with arguments

• __attribute(details): Non-standard GCC/Clang/IBM specific

• __declspec(details): Non-standard MSVC specific

Examples
[[noreturn]]

C++11

C++11 introduced the [[noreturn]] attribute. It can be used for a function to indicate that the
function does not return to the caller by either executing a return statement, or by reaching the end
if it's body (it is important to note that this does not apply to void functions, since they do return to
the caller, they just do not return any value). Such a function may end by calling std::terminate or
std::exit, or by throwing an exception. It is also worth noting that such a function can return by
executing longjmp.

For instance, the function below will always either throw an exception or call std::terminate, so it is
a good candidate for [[noreturn]]:

[[noreturn]] void ownAssertFailureHandler(std::string message) {


std::cerr << message << std::endl;
if (THROW_EXCEPTION_ON_ASSERT)
throw AssertException(std::move(message));
std::terminate();
}

This kind of functionality allows the compiler to end a function without a return statement if it
knows the code will never be executed. Here, because the call to ownAssertFailureHandler (defined
above) in the code below will never return, the compiler does not need to add code below that call:

std::vector<int> createSequence(int end) {


if (end > 0) {
std::vector<int> sequence;
sequence.reserve(end+1);
for (int i = 0; i <= end; ++i)
sequence.push_back(i);
return sequence;
}
ownAssertFailureHandler("Negative number passed to createSequence()"s);
// return std::vector<int>{}; //< Not needed because of [[noreturn]]

https://riptutorial.com/ 29
}

It is undefined behavior if the function will actually return, so the following is not allowed:

[[noreturn]] void assertPositive(int number) {


if (number >= 0)
return;
else
ownAssertFailureHandler("Positive number expected"s); //< [[noreturn]]
}

Note that the [[noreturn]] is mostly used in void functions. However, this is not a requirement,
allowing the functions to be used in generic programming:

template<class InconsistencyHandler>
double fortyTwoDivideBy(int i) {
if (i == 0)
i = InconsistencyHandler::correct(i);
return 42. / i;
}

struct InconsistencyThrower {
static [[noreturn]] int correct(int i) { ownAssertFailureHandler("Unknown
inconsistency"s); }
}

struct InconsistencyChangeToOne {
static int correct(int i) { return 1; }
}

double fortyTwo = fortyTwoDivideBy<InconsistencyChangeToOne>(0);


double unreachable = fortyTwoDivideBy<InconsistencyThrower>(0);

The following standard library functions have this attribute:

• std::abort
• std::exit
• std::quick_exit
• std::unexpected
• std::terminate
• std::rethrow_exception
• std::throw_with_nested
• std::nested_exception::rethrow_nested

[[fallthrough]]

C++17

Whenever a case is ended in a switch, the code of the next case will get executed. This last one
can be prevented by using the ´break` statement. As this so-called fallthrough behavior can
introduce bugs when not intended, several compilers and static analyzers give a warning on this.

https://riptutorial.com/ 30
From C++17 on, a standard attribute was introduced to indicate that the warning is not needed
when the code is meant to fall through. Compilers can safely give warnings when a case is ended
without break or [[fallthrough]] and has at least one statement.

switch(input) {
case 2011:
case 2014:
case 2017:
std::cout << "Using modern C++" << std::endl;
[[fallthrough]]; // > No warning
case 1998:
case 2003:
standard = input;
}

See the proposal for more detailed examples on how [[fallthrough]] can be used.

[[deprecated]] and [[deprecated("reason")]]

C++14

C++14 introduced a standard way of deprecating functions via attributes. [[deprecated]] can be
used to indicate that a function is deprecated. [[deprecated("reason")]] allows adding a specific
reason which can be shown by the compiler.

void function(std::unique_ptr<A> &&a);

// Provides specific message which helps other programmers fixing there code
[[deprecated("Use the variant with unique_ptr instead, this function will be removed in the
next release")]]
void function(std::auto_ptr<A> a);

// No message, will result in generic warning if called.


[[deprecated]]
void function(A *a);

This attribute may be applied to:

• the declaration of a class


• a typedef-name
• a variable
• a non-static data member
• a function
• an enumeration
• a template specialization

(ref. c++14 standard draft: 7.6.5 Deprecated attribute)

[[nodiscard]]

C++17

https://riptutorial.com/ 31
The [[nodiscard]] attribute can be used to indicate that the return value of a function shouldn't be
ignored when you do a function call. If the return value is ignored, the compiler should give a
warning on this. The attribute can be added to:

• A function definition
• A type

Adding the attribute to a type has the same behaviour as adding the attribute to every single
function which returns this type.

template<typename Function>
[[nodiscard]] Finally<std::decay_t<Function>> onExit(Function &&f);

void f(int &i) {


assert(i == 0); // Just to make comments clear!
++i; // i == 1
auto exit1 = onExit([&i]{ --i; }); // Reduce by 1 on exiting f()
++i; // i == 2
onExit([&i]{ --i; }); // BUG: Reducing by 1 directly
// Compiler warning expected
std::cout << i << std::end; // Expected: 2, Real: 1
}

See the proposal for more detailed examples on how [[nodiscard]] can be used.

Note: The implementation details of Finally/onExit are omitted in the example, see
Finally/ScopeExit.

[[maybe_unused]]

The [[maybe_unused]] attribute is created for indicating in code that certain logic might not be used.
This if often linked to preprocessor conditions where this might be used or might not be used. As
compilers can give warnings on unused variables, this is a way of suppressing them by indicating
intent.

A typical example of variables which are needed in debug builds while unneeded in production are
return values indicating success. In the debug builds, the condition should be asserted, though in
production these asserts have been removed.

[[maybe_unused]] auto mapInsertResult = configuration.emplace("LicenseInfo",


stringifiedLicenseInfo);
assert(mapInsertResult.second); // We only get called during startup, so we can't be in the
map

A more complex example are different kind of helper functions which are in an unnamed
namespace. If these functions aren't used during compilation, a compiler might give a warning on
them. Ideally you would like to guard them with the same preprocessor tags as the caller, though
as this might become complex the [[maybe_unused]] attribute is a more maintainable alternative.

namespace {
[[maybe_unused]] std::string createWindowsConfigFilePath(const std::string &relativePath);

https://riptutorial.com/ 32
// TODO: Reuse this on BSD, MAC ...
[[maybe_unused]] std::string createLinuxConfigFilePath(const std::string &relativePath);
}

std::string createConfigFilePath(const std::string &relativePath) {


#if OS == "WINDOWS"
return createWindowsConfigFilePath(relativePath);
#elif OS == "LINUX"
return createLinuxConfigFilePath(relativePath);
#else
#error "OS is not yet supported"
#endif
}

See the proposal for more detailed examples on how [[maybe_unused]] can be used.

Read Attributes online: https://riptutorial.com/cplusplus/topic/5251/attributes

https://riptutorial.com/ 33
Chapter 8: auto
Remarks
The keyword auto is a typename that represents an automatically-deduced type.

It was already a reserved keyword in C++98, inherited from C. In old versions of C++, it could be
used to explicitly state that a variable has automatic storage duration:

int main()
{
auto int i = 5; // removing auto has no effect
}

That old meaning is now removed.

Examples
Basic auto sample

The keyword auto provides the auto-deduction of type of a variable.

It is especially convenient when dealing with long type names:

std::map< std::string, std::shared_ptr< Widget > > table;


// C++98
std::map< std::string, std::shared_ptr< Widget > >::iterator i = table.find( "42" );
// C++11/14/17
auto j = table.find( "42" );

with range-based for loops:

vector<int> v = {0, 1, 2, 3, 4, 5};


for(auto n: v)
std::cout << n << ' ';

with lambdas:

auto f = [](){ std::cout << "lambda\n"; };


f();

to avoid the repetition of the type:

auto w = std::make_shared< Widget >();

to avoid surprising and unnecessary copies:

https://riptutorial.com/ 34
auto myMap = std::map<int,float>();
myMap.emplace(1,3.14);

std::pair<int,float> const& firstPair2 = *myMap.begin(); // copy!


auto const& firstPair = *myMap.begin(); // no copy!

The reason for the copy is that the returned type is actually std::pair<const int,float>!

auto and Expression Templates

auto can also cause problems where expression templates come into play:

auto mult(int c) {
return c * std::valarray<int>{1};
}

auto v = mult(3);
std::cout << v[0]; // some value that could be, but almost certainly is not, 3.

The reason is that operator* on valarray gives you a proxy object that refers to the valarray as a
means of lazy evaluation. By using auto, you're creating a dangling reference. Instead of mult had
returned a std::valarray<int>, then the code would definitely print 3.

auto, const, and references

The auto keyword by itself represents a value type, similar to int or char. It can be modified with
the const keyword and the & symbol to represent a const type or a reference type, respectively.
These modifiers can be combined.

In this example, s is a value type (its type will be inferred as std::string), so each iteration of the
for loop copies a string from the vector into s.

std::vector<std::string> strings = { "stuff", "things", "misc" };


for(auto s : strings) {
std::cout << s << std::endl;
}

If the body of the loop modifies s (such as by calling s.append(" and stuff")), only this copy will be
modified, not the original member of strings.

On the other hand, if s is declared with auto& it will be a reference type (inferred to be std::string&
), so on each iteration of the loop it will be assigned a reference to a string in the vector:

for(auto& s : strings) {
std::cout << s << std::endl;
}

In the body of this loop, modifications to s will directly affect the element of strings that it
references.

Finally, if s is declared const auto&, it will be a const reference type, meaning that on each iteration

https://riptutorial.com/ 35
of the loop it will be assigned a const reference to a string in the vector:

for(const auto& s : strings) {


std::cout << s << std::endl;
}

Within the body of this loop, s cannot be modified (i.e. no non-const methods can be called on it).

When using auto with range-based for loops, it is generally good practice to use const auto& if the
loop body will not modify the structure being looped over, since this avoids unnecessary copies.

Trailing return type

auto is used in the syntax for trailing return type:

auto main() -> int {}

which is equivalent to

int main() {}

Mostly useful combined with decltype to use parameters instead of std::declval<T>:

template <typename T1, typename T2>


auto Add(const T1& lhs, const T2& rhs) -> decltype(lhs + rhs) { return lhs + rhs; }

Generic lambda (C++14)

C++14

C++14 allows to use auto in lambda argument

auto print = [](const auto& arg) { std::cout << arg << std::endl; };

print(42);
print("hello world");

That lambda is mostly equivalent to

struct lambda {
template <typename T>
auto operator ()(const T& arg) const {
std::cout << arg << std::endl;
}
};

and then

lambda print;

https://riptutorial.com/ 36
print(42);
print("hello world");

auto and proxy objects

Sometimes auto may behave not quite as was expected by a programmer. It type deduces the
expression, even when type deduction is not the right thing to do.

As an example, when proxy objects are used in the code:

std::vector<bool> flags{true, true, false};


auto flag = flags[0];
flags.push_back(true);

Here flag would be not bool, but std::vector<bool>::reference, since for bool specialization of
template vector the operator [] returns a proxy object with conversion operator operator bool
defined.

When flags.push_back(true) modifies the container, this pseudo-reference could end up dangling,
referring to an element that no longer exists.

It also makes the next situation possible:

void foo(bool b);

std::vector<bool> getFlags();

auto flag = getFlags()[5];


foo(flag);

The vector is discarded immediately, so flag is a pseudo-reference to an element that has been
discarded. The call to foo invokes undefined behavior.

In cases like this you can declare a variable with auto and initialize it by casting to the type you
want to be deduced:

auto flag = static_cast<bool>(getFlags()[5]);

but at that point, simply replacing auto with bool makes more sense.

Another case where proxy objects can cause problems is expression templates. In that case, the
templates are sometimes not designed to last beyond the current full-expression for efficiency
sake, and using the proxy object on the next causes undefined behavior.

Read auto online: https://riptutorial.com/cplusplus/topic/2421/auto

https://riptutorial.com/ 37
Chapter 9: Basic input/output in c++
Remarks
The standard library <iostream> defines few streams for input and output:

|stream | description |
|-------|----------------------------------|
|cin | standard input stream |
|cout | standard output stream |
|cerr | standard error (output) stream |
|clog | standard logging (output) stream |

Out of four streams mentioned above cin is basically used for user input and other three are used
for outputting the data. In general or in most coding environments cin (console input or standard
input) is keyboard and cout (console output or standard output) is monitor.

cin >> value

cin - input stream


'>>' - extraction operator
value - variable (destination)

cin here extracts the input entered by the user and feeds in variable value. The value is extracted
only after user presses ENTER key.

cout << "Enter a value: "

cout - output stream


'<<' - insertion operator
"Enter a value: " - string to be displayed

cout here takes the string to be displayed and inserts it to standard output or monitor

All four streams are located in standard namespace std so we need to print std::stream for stream
stream to use it.

There is also a manipulator std::endl in code. It can be used only with output streams. It inserts
end of line '\n' character in the stream and flushes it. It causes immediately producing output.

Examples
user input and standard output

#include <iostream>

int main()
{

https://riptutorial.com/ 38
int value;
std::cout << "Enter a value: " << std::endl;
std::cin >> value;
std::cout << "The square of entered value is: " << value * value << std::endl;
return 0;
}

Read Basic input/output in c++ online: https://riptutorial.com/cplusplus/topic/10683/basic-input-


output-in-cplusplus

https://riptutorial.com/ 39
Chapter 10: Basic Type Keywords
Examples
int

Denotes a signed integer type with "the natural size suggested by the architecture of the execution
environment", whose range includes at least -32767 to +32767, inclusive.

int x = 2;
int y = 3;
int z = x + y;

Can be combined with unsigned, short, long, and long long (q.v.) in order to yield other integer
types.

bool

An integer type whose value can be either true or false.

bool is_even(int x) {
return x%2 == 0;
}
const bool b = is_even(47); // false

char

An integer type which is "large enough to store any member of the implementation’s basic
character set". It is implementation-defined whether char is signed (and has a range of at least -
127 to +127, inclusive) or unsigned (and has a range of at least 0 to 255, inclusive).

const char zero = '0';


const char one = zero + 1;
const char newline = '\n';
std::cout << one << newline; // prints 1 followed by a newline

char16_t

C++11

An unsigned integer type with the same size and alignment as uint_least16_t, which is therefore
large enough to hold a UTF-16 code unit.

const char16_t message[] = u" \n"; // Chinese for "hello, world\n"


std::cout << sizeof(message)/sizeof(char16_t) << "\n"; // prints 7

https://riptutorial.com/ 40
char32_t

C++11

An unsigned integer type with the same size and alignment as uint_least32_t, which is therefore
large enough to hold a UTF-32 code unit.

const char32_t full_house[] = U" "; // non-BMP characters


std::cout << sizeof(full_house)/sizeof(char32_t) << "\n"; // prints 6

float

A floating point type. Has the narrowest range out of the three floating point types in C++.

float area(float radius) {


const float pi = 3.14159f;
return pi*radius*radius;
}

double

A floating point type. Its range includes that of float. When combined with long, denotes the long
double floating point type, whose range includes that of double.

double area(double radius) {


const double pi = 3.141592653589793;
return pi*radius*radius;
}

long

Denotes a signed integer type that is at least as long as int, and whose range includes at least -
2147483647 to +2147483647, inclusive (that is, -(2^31 - 1) to +(2^31 - 1)). This type can also be
written as long int.

const long approx_seconds_per_year = 60L*60L*24L*365L;

The combination long double denotes a floating point type, which has the widest range out of the
three floating point types.

long double area(long double radius) {


const long double pi = 3.1415926535897932385L;
return pi*radius*radius;
}

C++11

When the long specifier occurs twice, as in long long, it denotes a signed integer type that is at
least as long as long, and whose range includes at least -9223372036854775807 to

https://riptutorial.com/ 41
+9223372036854775807, inclusive (that is, -(2^63 - 1) to +(2^63 - 1)).

// support files up to 2 TiB


const long long max_file_size = 2LL << 40;

short

Denotes a signed integer type that is at least as long as char, and whose range includes at least -
32767 to +32767, inclusive. This type can also be written as short int.

// (during the last year)


short hours_worked(short days_worked) {
return 8*days_worked;
}

void

An incomplete type; it is not possible for an object to have type void, nor are there arrays of void or
references to void. It is used as the return type of functions that do not return anything.

Moreover, a function may redundantly be declared with a single parameter of type void; this is
equivalent to declaring a function with no parameters (e.g. int main() and int main(void) declare
the same function). This syntax is allowed for compatibility with C (where function declarations
have a different meaning than in C++).

The type void* ("pointer to void") has the property that any object pointer can be converted to it
and back and result in the same pointer. This feature makes the type void* suitable for certain
kinds of (type-unsafe) type-erasing interfaces, for example for generic contexts in C-style APIs
(e.g. qsort, pthread_create).

Any expression may be converted to an expression of type void; this is called a discarded-value
expression:

static_cast<void>(std::printf("Hello, %s!\n", name)); // discard return value

This may be useful to signal explicitly that the value of an expression is not of interest and that the
expression is to be evaluated for its side effects only.

wchar_t

An integer type large enough to represent all characters of the largest supported extended
character set, also known as the wide-character set. (It is not portable to make the assumption
that wchar_t uses any particular encoding, such as UTF-16.)

It is normally used when you need to store characters over ASCII 255 , as it has a greater size
than the character type char.

const wchar_t message_ahmaric[] = L"ሰላም ልዑል\n"; //Ahmaric for "hello, world\n"

https://riptutorial.com/ 42
const wchar_t message_chinese[] = L" \n";// Chinese for "hello, world\n"
const wchar_t message_hebrew[] = L"‫\םלוע םולש‬n"; //Hebrew for "hello, world\n"
const wchar_t message_russian[] = L"Привет мир\n"; //Russian for "hello, world\n"
const wchar_t message_tamil[] = L"ஹலோ உலகம்\n"; //Tamil for "hello, world\n"

Read Basic Type Keywords online: https://riptutorial.com/cplusplus/topic/7839/basic-type-


keywords

https://riptutorial.com/ 43
Chapter 11: Bit fields
Introduction
Bit fields tightly pack C and C++ structures to reduce size. This appears painless: specify the
number of bits for members, and compiler does the work of co-mingling bits. The restriction is
inability to take the address of a bit field member, since it is stored co-mingled. sizeof() is also
disallowed.

The cost of bit fields is slower access, as memory must be retrieved and bitwise operations
applied to extract or modify member values. These operations also add to executable size.

Remarks
How expensive are the bitwise operations? Suppose a simple non-bit field structure:

struct foo {
unsigned x;
unsigned y;
}
static struct foo my_var;

In some later code:

my_var.y = 5;

If sizeof (unsigned) == 4, then x is stored at the start of the structure, and y is stored 4 bytes in.
Assembly code generated may resemble:

loada register1,#myvar ; get the address of the structure


storei register1[4],#0x05 ; put the value '5' at offset 4, e.g., set y=5

This is straightforward because x is not co-mingled with y. But imagine redefining the structure
with bit fields:

struct foo {
unsigned x : 4; /* Range 0-0x0f, or 0 through 15 */
unsigned y : 4;
}

Both x and y will be allocated 4 bits, sharing a single byte. The structure thus takes up 1 byte,
instead of 8. Consider the assembly to set y now, assuming it ends up in the upper nibble:

loada register1,#myvar ; get the address of the structure


loadb register2,register1[0] ; get the byte from memory
andb register2,#0x0f ; zero out y in the byte, leaving x alone
orb register2,#0x50 ; put the 5 into the 'y' portion of the byte

https://riptutorial.com/ 44
stb register1[0],register2 ; put the modified byte back into memory

This may be a good trade-off if we have thousands or millions of these structures, and it helps
keeps memory in cache or prevents swapping—or could bloat the executable to worsen these
problems and slow processing. As with all things, use good judgement.

Device driver use: Avoid bit fields as a clever implementation strategy for device drivers. Bit field
storage layouts are not necessarily consistent between compilers, making such implementations
non-portable. The read-modify-write to set values may not do what devices expect, causing
unexpected behaviors.

Examples
Declaration and Usage

struct FileAttributes
{
unsigned int ReadOnly: 1;
unsigned int Hidden: 1;
};

Here, each of these two fields will occupy 1 bit in memory. It is specified by : 1 expression after
the variable names. Base type of bit field could be any integral type (8-bit int to 64-bit int). Using
unsigned type is recommended, otherwise surprises may come.

If more bits are required, replace "1" with number of bits required. For example:

struct Date
{
unsigned int Year : 13; // 2^13 = 8192, enough for "year" representation for long time
unsigned int Month: 4; // 2^4 = 16, enough to represent 1-12 month values.
unsigned int Day: 5; // 32
};

The whole structure is using just 22 bits, and with normal compiler settings, sizeof this structure
would be 4 bytes.

Usage is pretty simple. Just declare the variable, and use it like ordinary structure.

Date d;

d.Year = 2016;
d.Month = 7;
d.Day = 22;

std::cout << "Year:" << d.Year << std::endl <<


"Month:" << d.Month << std::endl <<
"Day:" << d.Day << std::endl;

Read Bit fields online: https://riptutorial.com/cplusplus/topic/2710/bit-fields

https://riptutorial.com/ 45
Chapter 12: Bit Manipulation
Remarks
In order to use std::bitset you will have to include <bitset> header.

#include <bitset>

std::bitset overloads all of the operator functions to allow the same usage as the c-style handling
of bitsets.

References

• Bit Twiddling Hacks

Examples
Setting a bit

C-style bit manipulation


A bit can be set using the bitwise OR operator (|).

// Bit x will be set


number |= 1LL << x;

Using std::bitset
set(x) or set(x,true) - sets bit at position x to 1.

std::bitset<5> num(std::string("01100"));
num.set(0); // num is now 01101
num.set(2); // num is still 01101
num.set(4,true); // num is now 11110

Clearing a bit

C-style bit-manipulation
A bit can be cleared using the bitwise AND operator (&).

https://riptutorial.com/ 46
// Bit x will be cleared
number &= ~(1LL << x);

Using std::bitset
reset(x) or set(x,false) - clears the bit at position x.

std::bitset<5> num(std::string("01100"));
num.reset(2); // num is now 01000
num.reset(0); // num is still 01000
num.set(3,false); // num is now 00000

Toggling a bit

C-style bit-manipulation
A bit can be toggled using the XOR operator (^).

// Bit x will be the opposite value of what it is currently


number ^= 1LL << x;

Using std::bitset
std::bitset<4> num(std::string("0100"));
num.flip(2); // num is now 0000
num.flip(0); // num is now 0001
num.flip(); // num is now 1110 (flips all bits)

Checking a bit

C-style bit-manipulation
The value of the bit can be obtained by shifting the number to the right x times and then
performing bitwise AND (&) on it:

(number >> x) & 1LL; // 1 if the 'x'th bit of 'number' is set, 0 otherwise

The right-shift operation may be implemented as either an arithmetic (signed) shift or a logical
(unsigned) shift. If number in the expression number >> x has a signed type and a negative value, the
resulting value is implementation-defined.

If we need the value of that bit directly in-place, we could instead left shift the mask:

https://riptutorial.com/ 47
(number & (1LL << x)); // (1 << x) if the 'x'th bit of 'number' is set, 0 otherwise

Either can be used as a conditional, since all non-zero values are considered true.

Using std::bitset
std::bitset<4> num(std::string("0010"));
bool bit_val = num.test(1); // bit_val value is set to true;

Changing the nth bit to x

C-style bit-manipulation
// Bit n will be set if x is 1 and cleared if x is 0.
number ^= (-x ^ number) & (1LL << n);

Using std::bitset
set(n,val) - sets bit n to the value val.

std::bitset<5> num(std::string("00100"));
num.set(0,true); // num is now 00101
num.set(2,false); // num is now 00001

Set all bits

C-style bit-manipulation
x = -1; // -1 == 1111 1111 ... 1111b

(See here for an explanation of why this works and is actually the best approach.)

Using std::bitset
std::bitset<10> x;
x.set(); // Sets all bits to '1'

Remove rightmost set bit

https://riptutorial.com/ 48
C-style bit-manipulation
template <typename T>
T rightmostSetBitRemoved(T n)
{
// static_assert(std::is_integral<T>::value && !std::is_signed<T>::value, "type should be
unsigned"); // For c++11 and later
return n & (n - 1);
}

Explanation

• if n is zero, we have 0 & 0xFF..FF which is zero


• else n can be written 0bxxxxxx10..00 and n - 1 is 0bxxxxxx011..11, so n & (n - 1) is
0bxxxxxx000..00.

Counting bits set

The population count of a bitstring is often needed in cryptography and other applications and the
problem has been widely studied.

The naive way requires one iteration per bit:

unsigned value = 1234;


unsigned bits = 0; // accumulates the total number of bits set in `n`

for (bits = 0; value; value >>= 1)


bits += value & 1;

A nice trick (based on Remove rightmost set bit ) is:

unsigned bits = 0; // accumulates the total number of bits set in `n`

for (; value; ++bits)


value &= value - 1;

It goes through as many iterations as there are set bits, so it's good when value is expected to
have few nonzero bits.

The method was first proposed by Peter Wegner (in CACM 3 / 322 - 1960) and it's well known
since it appears in C Programming Language by Brian W. Kernighan and Dennis M. Ritchie.

This requires 12 arithmetic operations, one of which is a multication:

unsigned popcount(std::uint64_t x)
{
const std::uint64_t m1 = 0x5555555555555555; // binary: 0101...
const std::uint64_t m2 = 0x3333333333333333; // binary: 00110011..
const std::uint64_t m4 = 0x0f0f0f0f0f0f0f0f; // binary: 0000111100001111

https://riptutorial.com/ 49
x -= (x >> 1) & m1; // put count of each 2 bits into those 2 bits
x = (x & m2) + ((x >> 2) & m2); // put count of each 4 bits into those 4 bits
x = (x + (x >> 4)) & m4; // put count of each 8 bits into those 8 bits
return (x * h01) >> 56; // left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}

This kind of implementation has the best worst-case behavior (see Hamming weight for further
details).

Many CPUs have a specific instruction (like x86's popcnt) and the compiler could offer a specific (
non standard) built in function. E.g. with g++ there is:

int __builtin_popcount (unsigned x);

Check if an integer is a power of 2

The n & (n - 1) trick (see Remove rightmost set bit) is also useful to determine if an integer is a
power of 2:

bool power_of_2 = n && !(n & (n - 1));

Note that without the first part of the check (n &&), 0 is incorrectly considered a power of 2.

Bit Manipulation Application: Small to Capital Letter

One of several applications of bit manipulation is converting a letter from small to capital or vice
versa by choosing a mask and a proper bit operation. For example, the a letter has this binary
representation 01(1)00001 while its capital counterpart has 01(0)00001. They differ solely in the bit in
parenthesis. In this case, converting the a letter from small to capital is basically setting the bit in
parenthesis to one. To do so, we do the following:

/****************************************
convert small letter to captial letter.
========================================
a: 01100001
mask: 11011111 <-- (0xDF) 11(0)11111
:---------
a&mask: 01000001 <-- A letter
*****************************************/

The code for converting a letter to A letter is

#include <cstdio>

int main()
{
char op1 = 'a'; // "a" letter (i.e. small case)
int mask = 0xDF; // choosing a proper mask

https://riptutorial.com/ 50
printf("a (AND) mask = A\n");
printf("%c & 0xDF = %c\n", op1, op1 & mask);

return 0;
}

The result is

$ g++ main.cpp -o test1


$ ./test1
a (AND) mask = A
a & 0xDF = A

Read Bit Manipulation online: https://riptutorial.com/cplusplus/topic/3016/bit-manipulation

https://riptutorial.com/ 51
Chapter 13: Bit Operators
Remarks
Bit shift operations are not portable across all processor architectures, different processors can
have different bit-widths. In other words, if you wrote

int a = ~0;
int b = a << 1;

This value would be different on a 64 bit machine vs. on a 32 bit machine, or from an x86 based
processor to a PIC based processor.

Endian-ness does not need to be taken into account for the bit wise operations themselves, that is,
the right shift (>>) will shift the bits towards the least significant bit and an XOR will perform an
exclusive or on the bits. Endian-ness only needs to be taken into account with the data itself, that
is, if endian-ness is a concern for your application, it's a concern regardless of bit wise operations.

Examples
& - bitwise AND

int a = 6; // 0110b (0x06)


int b = 10; // 1010b (0x0A)
int c = a & b; // 0010b (0x02)

std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;

Output

a = 6, b = 10, c = 2

Why

A bit wise AND operates on the bit level and uses the following Boolean truth table:

TRUE AND TRUE = TRUE


TRUE AND FALSE = FALSE
FALSE AND FALSE = FALSE

When the binary value for a (0110) and the binary value for b (1010) are AND'ed together we get the
binary value of 0010:

int a = 0 1 1 0
int b = 1 0 1 0 &
---------
int c = 0 0 1 0

https://riptutorial.com/ 52
The bit wise AND does not change the value of the original values unless specifically assigned to
using the bit wise assignment compound operator &=:

int a = 5; // 0101b (0x05)


a &= 10; // a = 0101b & 1010b

| - bitwise OR

int a = 5; // 0101b (0x05)


int b = 12; // 1100b (0x0C)
int c = a | b; // 1101b (0x0D)

std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;

Output

a = 5, b = 12, c = 13

Why

A bit wise OR operates on the bit level and uses the following Boolean truth table:

true OR true = true


true OR false = true
false OR false = false

When the binary value for a (0101) and the binary value for b (1100) are OR'ed together we get the
binary value of 1101:

int a = 0 1 0 1
int b = 1 1 0 0 |
---------
int c = 1 1 0 1

The bit wise OR does not change the value of the original values unless specifically assigned to
using the bit wise assignment compound operator |=:

int a = 5; // 0101b (0x05)


a |= 12; // a = 0101b | 1101b

^ - bitwise XOR (exclusive OR)

int a = 5; // 0101b (0x05)


int b = 9; // 1001b (0x09)
int c = a ^ b; // 1100b (0x0C)

std::cout << "a = " << a << ", b = " << b << ", c = " << c << std::endl;

Output

a = 5, b = 9, c = 12

https://riptutorial.com/ 53
Why

A bit wise XOR (exclusive or) operates on the bit level and uses the following Boolean truth table:

true OR true = false


true OR false = true
false OR false = false

Notice that with an XOR operation true OR true = false where as with operations true AND/OR true
= true, hence the exclusive nature of the XOR operation.

Using this, when the binary value for a (0101) and the binary value for b (1001) are XOR'ed together
we get the binary value of 1100:

int a = 0 1 0 1
int b = 1 0 0 1 ^
---------
int c = 1 1 0 0

The bit wise XOR does not change the value of the original values unless specifically assigned to
using the bit wise assignment compound operator ^=:

int a = 5; // 0101b (0x05)


a ^= 9; // a = 0101b ^ 1001b

The bit wise XOR can be utilized in many ways and is often utilized in bit mask operations for
encryption and compression.

Note: The following example is often shown as an example of a nice trick. But should not be used
in production code (there are better ways std::swap() to achieve the same result).

You can also utilize an XOR operation to swap two variables without a temporary:

int a = 42;
int b = 64;

// XOR swap
a ^= b;
b ^= a;
a ^= b;

std::cout << "a = " << a << ", b = " << b << "\n";

To productionalize this you need to add a check to make sure it can be used.

void doXORSwap(int& a, int& b)


{
// Need to add a check to make sure you are not swapping the same
// variable with itself. Otherwise it will zero the value.
if (&a != &b)
{
// XOR swap

https://riptutorial.com/ 54
a ^= b;
b ^= a;
a ^= b;
}
}

So though it looks like a nice trick in isolation it is not useful in real code. xor is not a base logical
operation,but a combination of others: a^c=~(a&c)&(a|c)

also in 2015+ compilers variables may be assigned as binary:

int cn=0b0111;

~ - bitwise NOT (unary complement)

unsigned char a = 234; // 1110 1010b (0xEA)


unsigned char b = ~a; // 0001 0101b (0x15)

std::cout << "a = " << static_cast<int>(a) <<


", b = " << static_cast<int>(b) << std::endl;

Output

a = 234, b = 21

Why

A bit wise NOT (unary complement) operates on the bit level and simply flips each bit. If it's a 1, it's
changed to a 0, if it's a 0, it's changed to a 1. The bit wise NOT has the same effect as XOR'ing a
value against the max value for a specific type:

unsigned char a = 234; // 1110 1010b (0xEA)


unsigned char b = ~a; // 0001 0101b (0x15)
unsigned char c = a ^ ~0;

The bit wise NOT can also be a convenient way to check the maximum value for a specific integral
type:

unsigned int i = ~0;


unsigned char c = ~0;

std::cout << "max uint = " << i << std::endl <<


"max uchar = " << static_cast<short>(c) << std::endl;

The bit wise NOT does not change the value of the original value and does not have a compound
assignment operator, so you can not do a ~= 10 for example.

The bit wise NOT (~) should not be confused with the logical NOT (!); where a bit wise NOT will
flip each bit, a logical NOT will use the whole value to do its operation on, in other words (!1) !=
(~1)

https://riptutorial.com/ 55
<< - left shift

int a = 1; // 0001b
int b = a << 1; // 0010b

std::cout << "a = " << a << ", b = " << b << std::endl;

Output

a = 1, b = 2

Why

The left bit wise shift will shift the bits of the left hand value (a) the number specified on the right (1
), essentially padding the least significant bits with 0's, so shifting the value of 5 (binary 0000 0101)
to the left 4 times (e.g. 5 << 4) will yield the value of 80 (binary 0101 0000). You might note that
shifting a value to the left 1 time is also the same as multiplying the value by 2, example:

int a = 7;
while (a < 200) {
std::cout << "a = " << a << std::endl;
a <<= 1;
}

a = 7;
while (a < 200) {
std::cout << "a = " << a << std::endl;
a *= 2;
}

But it should be noted that the left shift operation will shift all bits to the left, including the sign bit,
example:

int a = 2147483647; // 0111 1111 1111 1111 1111 1111 1111 1111
int b = a << 1; // 1111 1111 1111 1111 1111 1111 1111 1110

std::cout << "a = " << a << ", b = " << b << std::endl;

Possible output: a = 2147483647, b = -2

While some compilers will yield results that seem expected, it should be noted that if you left shift
a signed number so that the sign bit is affected, the result is undefined. It is also undefined if the
number of bits you wish to shift by is a negative number or is larger than the number of bits the
type on the left can hold, example:

int a = 1;
int b = a << -1; // undefined behavior
char c = a << 20; // undefined behavior

The bit wise left shift does not change the value of the original values unless specifically assigned
to using the bit wise assignment compound operator <<=:

https://riptutorial.com/ 56
int a = 5; // 0101b
a <<= 1; // a = a << 1;

>> - right shift

int a = 2; // 0010b
int b = a >> 1; // 0001b

std::cout << "a = " << a << ", b = " << b << std::endl;

Output

a = 2, b = 1

Why

The right bit wise shift will shift the bits of the left hand value (a) the number specified on the right (
1); it should be noted that while the operation of a right shift is standard, what happens to the bits
of a right shift on a signed negative number is implementation defined and thus cannot be
guaranteed to be portable, example:

int a = -2;
int b = a >> 1; // the value of b will be depend on the compiler

It is also undefined if the number of bits you wish to shift by is a negative number, example:

int a = 1;
int b = a >> -1; // undefined behavior

The bit wise right shift does not change the value of the original values unless specifically
assigned to using the bit wise assignment compound operator >>=:

int a = 2; // 0010b
a >>= 1; // a = a >> 1;

Read Bit Operators online: https://riptutorial.com/cplusplus/topic/2572/bit-operators

https://riptutorial.com/ 57
Chapter 14: Build Systems
Introduction
C++, like C, has a long and varied history regarding compilation workflows and build processes.
Today, C++ has various popular build systems that are used to compile programs, sometimes for
multiple platforms within one build system. Here, a few build systems will be reviewed and
analyzed.

Remarks
Currently, there exists no universal or dominant build system for C++ that is both popular and
cross-platform. However, there do exist several major build systems that are attached to major
platforms/projects, the most notable being GNU Make with the GNU/Linux operating system and
NMAKE with the Visual C++/Visual Studio project system.

Additionally, some Integrated Development Environments (IDEs) also include specialized build
systems to be used specifically with the native IDE. Certain build system generators can generate
these native IDE build system/project formats, such as CMake for Eclipse and Microsoft Visual
Studio 2012.

Examples
Generating Build Environment with CMake

CMake generates build environments for nearly any compiler or IDE from a single project
definition. The following examples will demonstrate how to add a CMake file to the cross-platform
"Hello World" C++ code.

CMake files are always named "CMakeLists.txt" and should already exist in every project's root
directory (and possibly in sub-directories too.) A basic CMakeLists.txt file looks like:

cmake_minimum_required(VERSION 2.4)

project(HelloWorld)

add_executable(HelloWorld main.cpp)

See it live on Coliru.

This file tells CMake the project name, what file version to expect, and instructions to generate an
executable called "HelloWorld" that requires main.cpp.

Generate a build environment for your installed compiler/IDE from the command line:

> cmake .

https://riptutorial.com/ 58
Build the application with:

> cmake --build .

This generates the default build environment for the system, depending on the OS and installed
tools. Keep source code clean from any build artifacts with use of "out-of-source" builds:

> mkdir build


> cd build
> cmake ..
> cmake --build .

CMake can also abstract the platform shell's basic commands from the previous example:

> cmake -E make_directory build


> cmake -E chdir build cmake ..
> cmake --build build

CMake includes generators for a number of common build tools and IDEs. To generate makefiles
for Visual Studio's nmake:

> cmake -G "NMake Makefiles" ..


> nmake

Compiling with GNU make

Introduction
The GNU Make (styled make) is a program dedicated to the automation of executing shell
commands. GNU Make is one specific program that falls under the Make family. Make remains
popular among Unix-like and POSIX-like operating systems, including those derived from the
Linux kernel, Mac OS X, and BSD.

GNU Make is especially notable for being attached to the GNU Project, which is attached to the
popular GNU/Linux operating system. GNU Make also has compatible versions running on various
flavors of Windows and Mac OS X. It is also a very stable version with historical significance that
remains popular. It is for these reasons that GNU Make is often taught alongside C and C++.

Basic rules
To compile with make, create a Makefile in your project directory. Your Makefile could be as
simple as:

Makefile

# Set some variables to use in our command

https://riptutorial.com/ 59
# First, we set the compiler to be g++
CXX=g++

# Then, we say that we want to compile with g++'s recommended warnings and some extra ones.
CXXFLAGS=-Wall -Wextra -pedantic

# This will be the output file


EXE=app

SRCS=main.cpp

# When you call `make` at the command line, this "target" is called.
# The $(EXE) at the right says that the `all` target depends on the `$(EXE)` target.
# $(EXE) expands to be the content of the EXE variable
# Note: Because this is the first target, it becomes the default target if `make` is called
without target
all: $(EXE)

# This is equivalent to saying


# app: $(SRCS)
# $(SRCS) can be separated, which means that this target would depend on each file.
# Note that this target has a "method body": the part indented by a tab (not four spaces).
# When we build this target, make will execute the command, which is:
# g++ -Wall -Wextra -pedantic -o app main.cpp
# I.E. Compile main.cpp with warnings, and output to the file ./app
$(EXE): $(SRCS)
@$(CXX) $(CXXFLAGS) -o $@ $(SRCS)

# This target should reverse the `all` target. If you call


# make with an argument, like `make clean`, the corresponding target
# gets called.
clean:
@rm -f $(EXE)

NOTE: Make absolutely sure that the indentations are with a tab, not with four
spaces. Otherwise, you'll get an error of Makefile:10: *** missing separator. Stop.

To run this from the command-line, do the following:

$ cd ~/Path/to/project
$ make
$ ls
app main.cpp Makefile

$ ./app
Hello World!

$ make clean
$ ls
main.cpp Makefile

Incremental builds
When you start having more files, make becomes more useful. What if you edited a.cpp but not
b.cpp? Recompiling b.cpp would take more time.

https://riptutorial.com/ 60
With the following directory structure:

.
+-- src
| +-- a.cpp
| +-- a.hpp
| +-- b.cpp
| +-- b.hpp
+-- Makefile

This would be a good Makefile:

Makefile

CXX=g++
CXXFLAGS=-Wall -Wextra -pedantic
EXE=app

SRCS_GLOB=src/*.cpp
SRCS=$(wildcard $(SRCS_GLOB))
OBJS=$(SRCS:.cpp=.o)

all: $(EXE)

$(EXE): $(OBJS)
@$(CXX) -o $@ $(OBJS)

depend: .depend

.depend: $(SRCS)
@-rm -f ./.depend
@$(CXX) $(CXXFLAGS) -MM $^>>./.depend

clean:
-rm -f $(EXE)
-rm $(OBJS)
-rm *~
-rm .depend

include .depend

Again watch the tabs. This new Makefile ensures that you only recompile changed files,
minimizing compile time.

Documentation
For more on make, see the official documentation by the Free Software Foundation, the
stackoverflow documentation and dmckee's elaborate answer on stackoverflow.

Building with SCons

You can build the cross-platform "Hello World" C++ code, using Scons - A Python-language
software construction tool.

https://riptutorial.com/ 61
First, create a file called SConstruct (note that SCons will look for a file with this exact name by
default). For now, the file should be in a directory right along your hello.cpp. Write in the new file
the line

Program('hello.cpp')

Now, from the terminal, run scons. You should see something like

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o hello.o -c hello.cpp
g++ -o hello hello.o
scons: done building targets.

(although the details will vary depending on your operating system and installed compiler).

The Environment and Glob classes will help you further configure what to build. E.g., the SConstruct
file

env=Environment(CPPPATH='/usr/include/boost/',
CPPDEFINES=[],
LIBS=[],
SCONS_CXX_STANDARD="c++11"
)

env.Program('hello', Glob('src/*.cpp'))

builds the executable hello, using all cpp files in src. Its CPPPATH is /usr/include/boost and it
specifies the C++11 standard.

Ninja

Introduction
The Ninja build system is described by its project website as "a small build system with a focus on
speed." Ninja is designed to have its files generated by build system file generators, and takes a
low-level approach to build systems, in contrast to higher-level build system managers like CMake
or Meson.

Ninja is primarily written in C++ and Python, and was created as an alternative to the SCons build
system for the Chromium project.

NMAKE (Microsoft Program Maintenance Utility)

Introduction

https://riptutorial.com/ 62
NMAKE is a command-line utility developed by Microsoft to be used primarily in conjunction with
Microsoft Visual Studio and/or the Visual C++ command line tools.

NMAKE is build system that falls under the Make family of build systems, but has certain distinct
features that diverge from Unix-like Make programs, such as supporting Windows-specific file path
syntax (which itself differs from Unix-style file paths).

Autotools (GNU)

Introduction
The Autotools are a group of programs that create a GNU Build System for a given software
package. It is a suite of tools that work together to produce various build resources, such as a
Makefile (to be used with GNU Make). Thus, Autotools can be considered a de facto build system
generator.

Some notable Autotools programs include:

• Autoconf
• Automake (not to be confused with make)

In general, Autotools is meant to generate the Unix-compatible script and Makefile to allow the
following command to build (as well as install) most packages (in the simple case):

./configure && make && make install

As such, Autotools also has a relationship with certain package managers, especially those that
are attached to operating systems that conform to the POSIX Standard(s).

Read Build Systems online: https://riptutorial.com/cplusplus/topic/8200/build-systems

https://riptutorial.com/ 63
Chapter 15: C incompatibilities
Introduction
This describes what C code will break in a C++ compiler.

Examples
Reserved Keywords

The first example are keywords that have a special purpose in C++: the following is legal in C, but
not C++.

int class = 5

These errors are easy to fix: just rename the variable.

Weakly typed pointers

In C, pointers can be cast to a void*, which needs an explicit cast in C++. The following is illegal in
C++, but legal in C:

void* ptr;
int* intptr = ptr;

Adding an explicit cast makes this work, but can cause further issues.

goto or switch

In C++, you may not skip initializations with goto or switch. The following is valid in C, but not C++:

goto foo;
int skipped = 1;
foo;

These bugs may require redesign.

Read C incompatibilities online: https://riptutorial.com/cplusplus/topic/9645/c-incompatibilities

https://riptutorial.com/ 64
Chapter 16: C++ Containers
Introduction
C++ containers store a collection of elements. Containers include vectors, lists, maps, etc. Using
Templates, C++ containers contain collections of primitives (e.g. ints) or custom classes (e.g.
MyClass).

Examples
C++ Containers Flowchart

Choosing which C++ Container to use can be tricky, so here's a simple flowchart to help decide
which Container is right for the job.

https://riptutorial.com/ 65
https://riptutorial.com/ 66
Megan Hopkins

Read C++ Containers online: https://riptutorial.com/cplusplus/topic/10848/cplusplus-containers

https://riptutorial.com/ 67
Chapter 17: C++ Debugging and Debug-
prevention Tools & Techniques
Introduction
A lot of time from C++ developers is spent debugging. This topic is meant to assist with this task
and give inspiration for techniques. Don't expect an extensive list of issues and solutions fixed by
the tools or a manual on the mentioned tools.

Remarks
This topic ain't complete yet, examples on following techniques/tools would be useful:

• Mention more static analysis tools


• Binary instrumentation tools (like UBSan, TSan, MSan, ESan ...)
• Hardening (CFI ...)
• Fuzzing

Examples
My C++ program ends with segfault - valgrind

Let's have a basic failing program:

#include <iostream>

void fail() {
int *p1;
int *p2(NULL);
int *p3 = p1;
if (p3) {
std::cout << *p3 << std::endl;
}
}

int main() {
fail();
}

Build it (add -g to include debug info):

g++ -g -o main main.cpp

Run:

$ ./main

https://riptutorial.com/ 68
Segmentation fault (core dumped)
$

Let's debug it with valgrind:

$ valgrind ./main
==8515== Memcheck, a memory error detector
==8515== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8515== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8515== Command: ./main
==8515==
==8515== Conditional jump or move depends on uninitialised value(s)
==8515== at 0x400813: fail() (main.cpp:7)
==8515== by 0x40083F: main (main.cpp:13)
==8515==
==8515== Invalid read of size 4
==8515== at 0x400819: fail() (main.cpp:8)
==8515== by 0x40083F: main (main.cpp:13)
==8515== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8515==
==8515==
==8515== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==8515== Access not within mapped region at address 0x0
==8515== at 0x400819: fail() (main.cpp:8)
==8515== by 0x40083F: main (main.cpp:13)
==8515== If you believe this happened as a result of a stack
==8515== overflow in your program's main thread (unlikely but
==8515== possible), you can try to increase the size of the
==8515== main thread stack using the --main-stacksize= flag.
==8515== The main thread stack size used in this run was 8388608.
==8515==
==8515== HEAP SUMMARY:
==8515== in use at exit: 72,704 bytes in 1 blocks
==8515== total heap usage: 1 allocs, 0 frees, 72,704 bytes allocated
==8515==
==8515== LEAK SUMMARY:
==8515== definitely lost: 0 bytes in 0 blocks
==8515== indirectly lost: 0 bytes in 0 blocks
==8515== possibly lost: 0 bytes in 0 blocks
==8515== still reachable: 72,704 bytes in 1 blocks
==8515== suppressed: 0 bytes in 0 blocks
==8515== Rerun with --leak-check=full to see details of leaked memory
==8515==
==8515== For counts of detected and suppressed errors, rerun with: -v
==8515== Use --track-origins=yes to see where uninitialised values come from
==8515== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
$

First we focus on this block:

==8515== Invalid read of size 4


==8515== at 0x400819: fail() (main.cpp:8)
==8515== by 0x40083F: main (main.cpp:13)
==8515== Address 0x0 is not stack'd, malloc'd or (recently) free'd

The first line tells us that segfault is caused by reading 4 bytes. The second and the third lines are
call stack. It means that the invalid read is performed at the fail() function, line 8 of main.cpp,

https://riptutorial.com/ 69
which is called by main, line 13 of main.cpp.

Looking at line 8 of main.cpp we see

std::cout << *p3 << std::endl;

But we check the pointer first, so what's wrong? Lets check the other block:

==8515== Conditional jump or move depends on uninitialised value(s)


==8515== at 0x400813: fail() (main.cpp:7)
==8515== by 0x40083F: main (main.cpp:13)

It tells us that there is an unitialized variable at line 7 and we read it:

if (p3) {

Which points us to the line where we check p3 instead of p2. But how is it possible that p3 is
uninitialized? We initialize it by:

int *p3 = p1;

Valgrind advices us to rerun with --track-origins=yes, let's do it:

valgrind --track-origins=yes ./main

The argument for valgrind is just after valgrind. If we put it after our program, it would be passed to
our program.

The output is almost the same, there is only one difference:

==8517== Conditional jump or move depends on uninitialised value(s)


==8517== at 0x400813: fail() (main.cpp:7)
==8517== by 0x40083F: main (main.cpp:13)
==8517== Uninitialised value was created by a stack allocation
==8517== at 0x4007F6: fail() (main.cpp:3)

Which tells us that the uninitialized value we used at line 7 was created at line 3:

int *p1;

which guides us to our uninitialized pointer.

Segfault analysis with GDB

Lets use the same code as above for this example.

#include <iostream>

void fail() {

https://riptutorial.com/ 70
int *p1;
int *p2(NULL);
int *p3 = p1;
if (p3) {
std::cout << *p2 << std::endl;
}
}

int main() {
fail();
}

First lets compile it

g++ -g -o main main.cpp

Lets run it with gdb

gdb ./main

Now we will be in gdb shell. Type run.

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/opencog/code-snippets/stackoverflow/a.out

Program received signal SIGSEGV, Segmentation fault.


0x0000000000400850 in fail () at debugging_with_gdb.cc:11
11 std::cout << *p2 << std::endl;

We see the segmentation fault is happening at line 11. So the only variable being used at this line
is pointer p2. Lets examine its content typing print.

(gdb) print p2
$1 = (int *) 0x0

Now we see that p2 was initialized to 0x0 which stands for NULL. At this line, we know that we are
trying to dereference a NULL pointer. So we go and fix it.

Clean code

Debugging starts with understanding the code you are trying to debug.

Bad code:

int main() {
int value;
std::vector<int> vectorToSort;
vectorToSort.push_back(42); vectorToSort.push_back(13);
for (int i = 52; i; i = i - 1)
{

https://riptutorial.com/ 71
vectorToSort.push_back(i *2);
}
/// Optimized for sorting small vectors
if (vectorToSort.size() == 1);
else
{
if (vectorToSort.size() <= 2)
std::sort(vectorToSort.begin(), std::end(vectorToSort));
}
for (value : vectorToSort) std::cout << value << ' ';
return 0; }

Better code:

std::vector<int> createSemiRandomData() {
std::vector<int> data;
data.push_back(42);
data.push_back(13);
for (int i = 52; i; --i)
vectorToSort.push_back(i *2);
return data;
}

/// Optimized for sorting small vectors


void sortVector(std::vector &v) {
if (vectorToSort.size() == 1)
return;
if (vectorToSort.size() > 2)
return;

std::sort(vectorToSort.begin(), vectorToSort.end());
}

void printVector(const std::vector<int> &v) {


for (auto i : v)
std::cout << i << ' ';
}

int main() {
auto vectorToSort = createSemiRandomData();
sortVector(std::ref(vectorToSort));
printVector(vectorToSort);

return 0;
}

Regardless of the coding styles you prefer and use, having a consistent coding (and formatting)
style will help you understanding the code.

Looking at the code above, one can identify a couple of improvements to improve readability and
debuggability:

The use of separate functions for separate actions


The use of separate functions allow you to skip over some functions in the debugger if you ain't
interested in the details. In this specific case, you might not be interested in the creation or printing

https://riptutorial.com/ 72
of the data and only want to step into the sorting.

Another advantage is that you need to read less code (and memorize it) while stepping through
the code. You now only need to read 3 lines of code in main() in order to understand it, instead of
the whole function.

The third advantage is that you simply have less code to look at, which helps a trained eye in
spotting this bug within seconds.

Using consistent formatting/constructions


The use of consistent formatting and constructions will remove clutter from the code making it
easier to focus on the code instead of text. A lot of discussions have been fed on the 'right'
formatting style. Regardless of that style, having a single consistent style in the code will improve
familiarity and make it easier to focus on the code.

As formatting code is time consuming task, it is recommended to use a dedicated tool for this.
Most IDEs have at least some kind of support for this and can do formatting more consistent than
humans.

You might note that the style is not limited to spaces and newlines as we no longer mix the free-
style and the member functions to get begin/end of the container. (v.begin() vs std::end(v)).

Point attention to the important parts of your code.


Regardless of the style you determine to choose, the above code contains a couple of markers
which might give you a hint on what might be important:

• A comment stating optimized, this indicates some fancy techniques


• Some early returns in sortVector() indicate that we are doing something special
• The std::ref() indicates that something is going on with the sortVector()

Conclusion
Having clean code will help you understanding the code and will reduce the time you need to
debug it. In the second example, a code reviewer might even spot the bug at first glance, while the
bug might be hidden in the details in the first one. (PS: The bug is in the compare with 2.)

Static analysis

Static analysis is the technique in which on checks the code for patterns linked to known bugs.
Using this technique is less time consuming than a code review, though, its checks are only limited
to those programmed in the tool.

Checks can include the incorrect semi-colon behind the if-statement (if (var);) till advanced
graph algorithms which determine if a variable is not initialized.

https://riptutorial.com/ 73
Compiler warnings
Enabling static analysis is easy, the most simplistic version is already build-in in your compiler:

• clang++ -Wall -Weverything -Werror ...


• g++ -Wall -Weverything -Werror ...
• cl.exe /W4 /WX ...

If you enable these options, you will notice that each compiler will find bugs the others don't and
that you will get errors on techniques which might be valid or valid in a specific context. while
(staticAtomicBool); might be acceptable even if while (localBool); ain't.

So unlike code review, you are fighting a tool which understands your code, tells you a lot of useful
bugs and sometimes disagrees with you. In this last case, you might have to suppress the warning
locally.

As the options above enable all warnings, they might enable warnings you don't want. (Why
should your code be C++98 compatible?) If so, you can simply disable that specific warning:

• clang++ -Wall -Weverything -Werror -Wno-errortoaccept ...


• g++ -Wall -Weverything -Werror -Wno-errortoaccept ...
• cl.exe /W4 /WX /wd<no of warning>...

Where compiler warnings assist you during development, they slow down compilation quite a bit.
That is why you might not always want to enable them by default. Either you run them by default
or you enable some continuous integration with the more expensive checks (or all of them).

External tools
If you decide to have some continuous integration, the use of other tools ain't such a stretch. A
tool like clang-tidy has an list of checks which covers a wide range of issues, some examples:

• Actual bugs
Prevention of slicing

Asserts with side effects


• Readability checks
Misleading indentation

Check identifier naming


• Modernization checks
Use make_unique()

Use nullptr

• Performance checks
Find unneeded copies

Find inefficient algorithm calls


The list might not be that large, as Clang already has a lot of compiler warnings, however it will
bring you one step closer to a high quality code base.

https://riptutorial.com/ 74
Other tools
Other tools with similar purpose exist, like:

• the visual studio static analyzer as external tool


• clazy, a Clang compiler plugin for checking Qt code

Conclusion
A lot static analysis tools exist for C++, both build-in in the compiler as external tools. Trying them
out doesn't take that much time for easy setups and they will find bugs you might miss in code
review.

Safe-stack (Stack corruptions)

Stack corruptions are annoying bugs to look at. As the stack is corrupted, the debugger often can't
give you a good stack trace of where you are and how you got there.

This is where safe-stack comes into play. Instead of using a single stack for your threads, it will
use two: A safe stack and a dangerous stack. The safe stack works exactly like it did before,
except that some parts are moved to the dangerous stack.

Which parts of the stack get moved?


Every part which has the potential of corrupting the stack will get moved out of the safe stack. As
soon as a variable on the stack gets passed by reference or one takes the address of this variable,
the compiler will decide to allocate this on the second stack instead of the safe one.

As a result, any operation you do with those pointers, any modification you make on the memory
(based on those pointers/references) can only effect the memory in the second stack. As one
never gets a pointer which is close to the safe stack, the stack cannot corrupt the stack and the
debugger can still read all functions on the stack to give a nice trace.

What is it actually used for?


The safe stack was not invented to give you better debugging experience, however, it is a nice
side effect for nasty bugs. It's original purpose is as part of the Code-Pointer Integrity (CPI) Project
, in which they try to prevent overriding the return addresses to prevent code injection. In other
words, they try to prevent executing a hackers code.

For this reason, the feature has been activated on chromium and has been reported to have a
<1% CPU overhead.

How to enable it?

https://riptutorial.com/ 75
Right now, the option is only available in the clang compiler, where one can pass -fsanitize=safe-
stack to the compiler. A proposal was made to implement the same feature in GCC.

Conclusion
Stack corruptions can become easier to debug when safe stack is enabled. Due to a low
performance overhead, you can even activated by default in your build configuration.

Read C++ Debugging and Debug-prevention Tools & Techniques online:


https://riptutorial.com/cplusplus/topic/9814/cplusplus-debugging-and-debug-prevention-tools---
techniques

https://riptutorial.com/ 76
Chapter 18: C++ function "call by value" vs.
"call by reference"
Introduction
The scope of this section is to explain the differences in theory and implementation for what
happens with the parameters of a function upon calling.

In detail the parameters can be seen as variables before the function call and inside the function,
where the visible behaviour and accessibility to these variables differs with the method used to
hand them over.

Additionally, the reusability of variables and their respective values after the function call also is
explained by this topic.

Examples
Call by value

Upon calling a function there are new elements created on the program stack. These include
some information about the function and also space (memory locations) for the parameters and
the return value.

When handing over a parameter to a function the value of the used variable (or literal) is copied
into the memory location of the function parameter. This implies that now there a two memory
locations with the same value. Inside of the function we only work on the parameter memory
location.

After leaving the function the memory on the program stack is popped (removed) which erases all
data of the function call, including the memory location of the parameters we used inside. Thus,
the values changed inside the function do not affect the outside variables values.

int func(int f, int b) {


//new variables are created and values from the outside copied
//f has a value of 0
//inner_b has a value of 1
f = 1;
//f has a value of 1
b = 2;
//inner_b has a value of 2
return f+b;
}

int main(void) {
int a = 0;
int b = 1; //outer_b
int c;

https://riptutorial.com/ 77
c = func(a,b);
//the return value is copied to c

//a has a value of 0


//outer_b has a value of 1 <--- outer_b and inner_b are different variables
//c has a value of 3
}

In this code we create variables inside the main function. These get assigned values. Upon calling
the functions there are two new variables created: f and inner_b where b shares the name with the
outer variable it does not share the memory location. The behaviour of a<->f and b<->b is identical.

The following graphic symbolizes what is happening on the stack and why there is no change in
varibale b. The graphic is not fully accurate but emphazises the example.

It is called "call by value" because we do not hand over the variables but only the values of these
variables.

Read C++ function "call by value" vs. "call by reference" online:


https://riptutorial.com/cplusplus/topic/10669/cplusplus-function--call-by-value--vs---call-by-
reference-

https://riptutorial.com/ 78
Chapter 19: C++ Streams
Remarks
Default constructor of std::istream_iterator constructs an iterator which represents the end of the
stream. Thus, std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(), ....
means to copy from the current position in ifs to the end.

Examples
String streams

std::ostringstream is a class whose objects look like an output stream (that is, you can write to
them via operator<<), but actually store the writing results, and provide them in the form of a
stream.

Consider the following short code:

#include <sstream>
#include <string>

using namespace std;

int main()
{
ostringstream ss;
ss << "the answer to everything is " << 42;
const string result = ss.str();
}

The line

ostringstream ss;

creates such an object. This object is first manipulated like a regular stream:

ss << "the answer to everything is " << 42;

Following that, though, the resulting stream can be obtained like this:

const string result = ss.str();

(the string result will be equal to "the answer to everything is 42").

This is mainly useful when we have a class for which stream serialization has been defined, and
for which we want a string form. For example, suppose we have some class

https://riptutorial.com/ 79
class foo
{
// All sort of stuff here.
};

ostream &operator<<(ostream &os, const foo &f);

To get the string representation of a foo object,

foo f;

we could use

ostringstream ss;
ss << f;
const string result = ss.str();

Then result contains the string representation of the foo object.

Reading a file till the end

Reading a text file line-by-line


A proper way to read a text file line-by-line till the end is usually not clear from ifstream
documentation. Let's consider some common mistakes done by beginner C++ programmers, and
a proper way to read the file.

Lines without whitespace characters


For the sake of simplicity, let's assume that each line in the file contains no whitespace symbols.

ifstreamhas operator bool(), which returns true when a stream has no errors and is ready to read.
Moreover, ifstream::operator >> returns a reference to the stream itself, so we can read and check
for EOF (as well as for errors) in one line with very elegant syntax:

std::ifstream ifs("1.txt");
std::string s;
while(ifs >> s) {
std::cout << s << std::endl;
}

Lines with whitespace characters


ifstream::operator >> reads the stream until any whitespace character occurs, so the above code
will print the words from a line on separate lines. To read everything till the end of line, use
std::getline instead of ifstream::operator >>. getline returns reference to the thread it worked
with, so the same syntax is available:

https://riptutorial.com/ 80
while(std::getline(ifs, s)) {
std::cout << s << std::endl;
}

Obviously, std::getline should also be used for reading a single-line file till the end.

Reading a file into a buffer at once


Finally, let's read the file from the beginning till the end without stopping at any character, including
whitespaces and newlines. If we know the exact file size or upper bound of the length is
acceptable, we can resize the string and then read:

s.resize(100);
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
s.begin());

Otherwise, we need to insert each character to the end of the string, so std::back_inserter is what
we need:

std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
std::back_inserter(s));

Alternatively, it is possible to initialize a collection with stream data, using a constructor with
iterator range arguments:

std::vector v(std::istreambuf_iterator<char>(ifs),
std::istreambuf_iterator<char>());

Note that these examples are also applicable if ifs is opened as binary file:

std::ifstream ifs("1.txt", std::ios::binary);

Copying streams
A file may be copied to another file with streams and iterators:

std::ofstream ofs("out.file");
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
std::ostream_iterator<char>(ofs));
ofs.close();

or redirected to any other type of stream with a compatible interface. For example Boost.Asio
network stream:

boost::asio::ip::tcp::iostream stream;
stream.connect("example.com", "http");

https://riptutorial.com/ 81
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(),
std::ostream_iterator<char>(stream));
stream.close();

Arrays
As iterators might be thought of as a generalization of pointers, STL containers in the examples
above may be replaced with native arrays. Here is how to parse numbers into array:

int arr[100];
std::copy(std::istream_iterator<char>(ifs), std::istream_iterator<char>(), arr);

Beware of buffer overflow, as arrays cannot be resized on-the-fly after they were allocated. For
example, if the code above will be fed with a file that contains more than 100 integer numbers, it
will attempt to write outside the array and run into undefined behavior.

Printing collections with iostream

Basic printing
std::ostream_iterator allows to print contents of an STL container to any output stream without
explicit loops. The second argument of std::ostream_iterator constructor sets the delimiter. For
example, the following code:

std::vector<int> v = {1,2,3,4};
std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " ! "));

will print

1 ! 2 ! 3 ! 4 !

Implicit type cast


std::ostream_iterator allows to cast container's content type implicitly. For example, let's tune
std::cout to print floating-point values with 3 digits after decimal point:

std::cout << std::setprecision(3);


std::fixed(std::cout);

and instantiate std::ostream_iterator with float, while the contained values remain int:

std::vector<int> v = {1,2,3,4};
std::copy(v.begin(), v.end(), std::ostream_iterator<float>(std::cout, " ! "));

https://riptutorial.com/ 82
so the code above yields

1.000 ! 2.000 ! 3.000 ! 4.000 !

despite std::vector holds ints.

Generation and transformation


std::generate, std::generate_nand std::transform functions provide a very powerful tool for on-the-
fly data manipulation. For example, having a vector:

std::vector<int> v = {1,2,3,4,8,16};

we can easily print boolean value of "x is even" statement for each element:

std::boolalpha(std::cout); // print booleans alphabetically


std::transform(v.begin(), v.end(), std::ostream_iterator<bool>(std::cout, " "),
[](int val) {
return (val % 2) == 0;
});

or print the squared element:

std::transform(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "),


[](int val) {
return val * val;
});

Printing N space-delimited random numbers:

const int N = 10;


std::generate_n(std::ostream_iterator<int>(std::cout, " "), N, std::rand);

Arrays
As in the section about reading text files, almost all these considerations may be applied to native
arrays. For example, let's print squared values from a native array:

int v[] = {1,2,3,4,8,16};


std::transform(v, std::end(v), std::ostream_iterator<int>(std::cout, " "),
[](int val) {
return val * val;
});

Parsing files

https://riptutorial.com/ 83
Parsing files into STL containers
istream_iteratorsare very useful for reading sequences of numbers or other parsable data into
STL containers without explicit loops in the code.

Using explicit container size:

std::vector<int> v(100);
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
v.begin());

or with inserting iterator:

std::vector<int> v;
std::copy(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
std::back_inserter(v));

Note that the numbers in the input file may be divided by any number of any whitespace
characters and newlines.

Parsing heterogeneous text tables


As istream::operator>> reads text until a whitespace symbol, it may be used in while condition to
parse complex data tables. For example, if we have a file with two real numbers followed by a
string (without spaces) on each line:

1.12 3.14 foo


2.1 2.2 barr

it may be parsed like this:

std::string s;
double a, b;
while(ifs >> a >> b >> s) {
std::cout << a << " " << b << " " << s << std::endl;
}

Transformation
Any range-manipulating function may be used with std::istream_iterator ranges. One of them is
std::transform, which allows to process data on-the-fly. For example, let's read integer values,
multiply them by 3.14 and store the result into floating-point container:

std::vector<double> v(100);
std::transform(std::istream_iterator<int>(ifs), std::istream_iterator<int>(),
v.begin(),

https://riptutorial.com/ 84
[](int val) {
return val * 3.14;
});

Read C++ Streams online: https://riptutorial.com/cplusplus/topic/7660/cplusplus-streams

https://riptutorial.com/ 85
Chapter 20: C++11 Memory Model
Remarks
Different threads trying to access the same memory location participate in a data race if at least
one of the operations is a modification (also known as store operation). These data races cause
undefined behavior. To avoid them one needs to prevent these threads from concurrently
executing such conflicting operations.

Synchronization primitives (mutex, critical section and the like) can guard such accesses. The
Memory Model introduced in C++11 defines two new portable ways to synchronize access to
memory in multi-threaded environment: atomic operations and fences.

Atomic Operations
It is now possible to read and write to given memory location by the use of atomic load and atomic
store operations. For convenience these are wrapped in the std::atomic<t> template class. This
class wraps a value of type t but this time loads and stores to the object are atomic.

The template is not available for all types. Which types are available is implementation specific,
but this usually includes most (or all) available integral types as well as pointer types. So that
std::atomic<unsigned> and std::atomic<std::vector<foo> *> should be available, while
std::atomic<std::pair<bool,char>> most probably wont be.

Atomic operations have the following properties:

• All atomic operations can be performed concurrently from multiple threads without causing
undefined behavior.
• An atomic load will see either the initial value which the atomic object was constructed with,
or the value written to it via some atomic store operation.
• Atomic stores to the same atomic object are ordered the same in all threads. If a thread has
already seen the value of some atomic store operation, subsequent atomic load operations
will see either the same value, or the value stored by subsequent atomic store operation.
• Atomic read-modify-write operations allow atomic load and atomic store to happen without
other atomic store in between. For example one can atomically increment a counter from
multiple threads, and no increment will be lost regardless of the contention between the
threads.
• Atomic operations receive an optional std::memory_order parameter which defines what
additional properties the operation has regarding other memory locations.

std::memory_order Meaning

std::memory_order_relaxed no additional restrictions

std::memory_order_release → if load-acquire sees the value stored by store-release

https://riptutorial.com/ 86
std::memory_order Meaning

std::memory_order_acquire then stores sequenced before the store-release happen


before loads sequenced after the load acquire

std::memory_order_consume like memory_order_acquire but only for dependent loads

std::memory_order_acq_rel combines load-acquire and store-release

std::memory_order_seq_cst sequential consistency

These memory order tags allow three different memory ordering disciplines: sequential
consistency, relaxed, and release-acquire with its sibling release-consume.

Sequential Consistency

If no memory order is specified for an atomic operation, the order defaults to sequential
consistency. This mode can also be explicitly selected by tagging the operation with
std::memory_order_seq_cst.

With this order no memory operation can cross the atomic operation. All memory operations
sequenced before the atomic operation happen before the atomic operation and the atomic
operation happens before all memory operations that are sequenced after it. This mode is
probably the easiest one to reason about but it also leads to the greatest penalty to performance.
It also prevents all compiler optimizations that might otherwise try to reorder operations past the
atomic operation.

Relaxed Ordering

The opposite to sequential consistency is the relaxed memory ordering. It is selected with the
std::memory_order_relaxed tag. Relaxed atomic operation will impose no restrictions on other
memory operations. The only effect that remains, is that the operation is itself still atomic.

Release-Acquire Ordering

An atomic store operation can be tagged with std::memory_order_release and an atomic load
operation can be tagged with std::memory_order_acquire. The first operation is called (atomic)
store-release while the second is called (atomic) load-acquire.

When load-acquire sees the value written by a store-release the following happens: all store
operations sequenced before the store-release become visible to (happen before) load operations
that are sequenced after the load-acquire.

Atomic read-modify-write operations can also receive the cumulative tag std::memory_order_acq_rel
. This makes the atomic load portion of the operation an atomic load-acquire while the atomic
store portion becomes atomic store-release.

The compiler is not allowed to move store operations after an atomic store-release operation. It is

https://riptutorial.com/ 87
also not allowed to move load operations before atomic load-acquire (or load-consume).

Also note that there is no atomic load-release or atomic store-acquire. Attempting to create such
operations makes them relaxed operations.

Release-Consume Ordering

This combination is similar to release-acquire, but this time the atomic load is tagged with
std::memory_order_consume and becomes (atomic) load-consume operation. This mode is the same
as release-acquire with the only difference that among the load operations sequenced after the
load-consume only these depending on the value loaded by the load-consume are ordered.

Fences
Fences also allow memory operations to be ordered between threads. A fence is either a release
fence or acquire fence.

If a release fence happens before an acquire fence, then stores sequenced before the release
fence are visible to loads sequenced after the acquire fence. To guarantee that the release fence
happens before the acquire fence one may use other synchronization primitives including relaxed
atomic operations.

Examples
Need for Memory Model

int x, y;
bool ready = false;

void init()
{
x = 2;
y = 3;
ready = true;
}
void use()
{
if (ready)
std::cout << x + y;
}

One thread calls the init() function while another thread (or signal handler) calls the use()
function. One might expect that the use() function will either print 5 or do nothing. This may not
always be the case for several reasons:

• The CPU may reorder the writes that happen in init() so that the code that actually
executes might look like:

https://riptutorial.com/ 88
void init()
{
ready = true;
x = 2;
y = 3;
}

• The CPU may reorder the reads that happen in use() so that the actually executed code
might become:

void use()
{
int local_x = x;
int local_y = y;
if (ready)
std::cout << local_x + local_y;
}

• An optimizing C++ compiler may decide to reorder the program in similar way.

Such reordering cannot change the behavior of a program running in single thread because a
thread cannot interleave the calls to init() and use(). On the other hand in a multi-threaded
setting one thread may see part of the writes performed by the other thread where it may happen
that use() may see ready==true and garbage in x or y or both.

The C++ Memory Model allows the programmer to specify which reordering operations are
permitted and which are not, so that a multi-threaded program would also be able to behave as
expected. The example above can be rewritten in thread-safe way like this:

int x, y;
std::atomic<bool> ready{false};

void init()
{
x = 2;
y = 3;
ready.store(true, std::memory_order_release);
}
void use()
{
if (ready.load(std::memory_order_acquire))
std::cout << x + y;
}

Here init() performs atomic store-release operation. This not only stores the value true into ready,
but also tells the compiler that it cannot move this operation before write operations that are
sequenced before it.

The use() function does an atomic load-acquire operation. It reads the current value of ready and
also forbids the compiler from placing read operations that are sequenced after it to happen before
the atomic load-acquire.

These atomic operations also cause the compiler to put whatever hardware instructions are

https://riptutorial.com/ 89
needed to inform the CPU to refrain from the unwanted reorderings.

Because the atomic store-release is to the same memory location as the atomic load-acquire, the
memory model stipulates that if the load-acquire operation sees the value written by the store-
release operation, then all writes performed by init()'s thread prior to that store-release will be
visible to loads that use()'s thread executes after its load-acquire. That is if use() sees ready==true,
then it is guaranteed to see x==2 and y==3.

Note that the compiler and the CPU are still allowed to write to y before writing to x, and similarly
the reads from these variables in use() can happen in any order.

Fence example

The example above can also be implemented with fences and relaxed atomic operations:

int x, y;
std::atomic<bool> ready{false};

void init()
{
x = 2;
y = 3;
atomic_thread_fence(std::memory_order_release);
ready.store(true, std::memory_order_relaxed);
}
void use()
{
if (ready.load(std::memory_order_relaxed))
{
atomic_thread_fence(std::memory_order_acquire);
std::cout << x + y;
}
}

If the atomic load operation sees the value written by the atomic store then the store happens
before the load, and so do the fences: the release fence happens before the acquire fence making
the writes to x and y that precede the release fence to become visible to the std::cout statement
that follows the acquire fence.

A fence might be beneficial if it can reduce the overall number of acquire, release or other
synchronization operations. For example:

void block_and_use()
{
while (!ready.load(std::memory_order_relaxed))
;
atomic_thread_fence(std::memory_order_acquire);
std::cout << x + y;
}

The block_and_use() function spins until the ready flag is set with the help of relaxed atomic load.
Then a single acquire fence is used to provide the needed memory ordering.

https://riptutorial.com/ 90
Read C++11 Memory Model online: https://riptutorial.com/cplusplus/topic/7975/cplusplus11-
memory-model

https://riptutorial.com/ 91
Chapter 21: Callable Objects
Introduction
Callable objects are the collection of all C++ structures which can be used as a function. In
practice, this are all things you can pass to the C++17 STL function invoke() or which can be used
in the constructor of std::function, this includes: Function pointers, Classes with operator(),
Classes with implicit conversions, References to functions, Pointers to member functions, Pointers
to member data, lambdas. The callable objects are used in many STL algorithms as predicate.

Remarks
A very useful talk by Stephan T. Lavavej (<functional>: What's New, And Proper Use) (Slides)
leads to the base of this documentation.

Examples
Function Pointers

Function pointers are the most basic way of passing functions around, which can also be used in
C. (See the C documentation for more details).

For the purpose of callable objects, a function pointer can be defined as:

typedef returnType(*name)(arguments); // All


using name = returnType(*)(arguments); // <= C++11
using name = std::add_pointer<returnType(arguments)>::type; // <= C++11
using name = std::add_pointer_t<returnType(arguments)>; // <= C++14

If we would be using a function pointer for writing our own vector sort, it would look like:

using LessThanFunctionPtr = std::add_pointer_t<bool(int, int)>;


void sortVectorInt(std::vector<int>&v, LessThanFunctionPtr lessThan) {
if (v.size() < 2)
return;
if (v.size() == 2) {
if (!lessThan(v.front(), v.back())) // Invoke the function pointer
std::swap(v.front(), v.back());
return;
}
std::sort(v, lessThan);
}

bool lessThanInt(int lhs, int rhs) { return lhs < rhs; }


sortVectorInt(vectorOfInt, lessThanInt); // Passes the pointer to a free function

struct GreaterThanInt {
static bool cmp(int lhs, int rhs) { return lhs > rhs; }
};

https://riptutorial.com/ 92
sortVectorInt(vectorOfInt, &GreaterThanInt::cmp); // Passes the pointer to a static member
function

Alternatively, we could have invoked the function pointer one of following ways:

• (*lessThan)(v.front(), v.back()) // All


• std::invoke(lessThan, v.front(), v.back()) // <= C++17

Classes with operator() (Functors)

Every class which overloads the operator() can be used as a function object. These classes can
be written by hand (often referred to as functors) or automatically generated by the compiler by
writing Lambdas from C++11 on.

struct Person {
std::string name;
unsigned int age;
};

// Functor which find a person by name


struct FindPersonByName {
FindPersonByName(const std::string &name) : _name(name) {}

// Overloaded method which will get called


bool operator()(const Person &person) const {
return person.name == _name;
}
private:
std::string _name;
};

std::vector<Person> v; // Assume this contains data


std::vector<Person>::iterator iFind =
std::find_if(v.begin(), v.end(), FindPersonByName("Foobar"));
// ...

As functors have their own identity, they cannot be put in a typedef and these have to be accepted
via template argument. The definition of std::find_if can look like:

template<typename Iterator, typename Predicate>


Iterator find_if(Iterator begin, Iterator end, Predicate &predicate) {
for (Iterator i = begin, i != end, ++i)
if (predicate(*i))
return i;
return end;
}

From C++17 on, the calling of the predicate can be done with invoke: std::invoke(predicate, *i).

Read Callable Objects online: https://riptutorial.com/cplusplus/topic/6073/callable-objects

https://riptutorial.com/ 93
Chapter 22: Classes/Structures
Syntax
• variable.member_var = constant;
• variable.member_function();
• variable_pointer->member_var = constant;
• variable_pointer->member_function();

Remarks
Note that the only difference between the struct and class keywords is that by default, the
member variables, member functions, and base classes of a struct are public, while in a class
they are private. C++ programmers tend to call it a class if it has constructors and destructors, and
the ability to enforce its own invariants; or a struct if it's just a simple collection of values, but the
C++ language itself makes no distinction.

Examples
Class basics

A class is a user-defined type. A class is introduced with the class, struct or union keyword. In
colloquial usage, the term "class" usually refers only to non-union classes.

A class is a collection of class members, which can be:

• member variables (also called "fields"),


• member functions (also called "methods"),
• member types or typedefs (e.g. "nested classes"),
• member templates (of any kind: variable, function, class or alias template)

The class and struct keywords, called class keys, are largely interchangeable, except that the
default access specifier for members and bases is "private" for a class declared with the class key
and "public" for a class declared with the struct or union key (cf. Access modifiers).

For example, the following code snippets are identical:

struct Vector
{
int x;
int y;
int z;
};
// are equivalent to
class Vector
{
public:

https://riptutorial.com/ 94
int x;
int y;
int z;
};

By declaring a class` a new type is added to your program, and it is possible to instantiate objects
of that class by

Vector my_vector;

Members of a class are accessed using dot-syntax.

my_vector.x = 10;
my_vector.y = my_vector.x + 1; // my_vector.y = 11;
my_vector.z = my_vector.y - 4; // my:vector.z = 7;

Access specifiers

There are three keywords that act as access specifiers. These limit the access to class members
following the specifier, until another specifier changes the access level again:

Keyword Description

public Everyone has access

protected Only the class itself, derived classes and friends have access

private Only the class itself and friends have access

When the type is defined using the class keyword, the default access specifier is private, but if the
type is defined using the struct keyword, the default access specifier is public:

struct MyStruct { int x; };


class MyClass { int x; };

MyStruct s;
s.x = 9; // well formed, because x is public

MyClass c;
c.x = 9; // ill-formed, because x is private

Access specifiers are mostly used to limit access to internal fields and methods, and force the
programmer to use a specific interface, for example to force use of getters and setters instead of
referencing a variable directly:

class MyClass {

public: /* Methods: */

int x() const noexcept { return m_x; }

https://riptutorial.com/ 95
void setX(int const x) noexcept { m_x = x; }

private: /* Fields: */

int m_x;

};

Using protected is useful for allowing certain functionality of the type to be only accessible to the
derived classes, for example, in the following code, the method calculateValue() is only accessible
to classes deriving from the base class Plus2Base, such as FortyTwo:

struct Plus2Base {
int value() noexcept { return calculateValue() + 2; }
protected: /* Methods: */
virtual int calculateValue() noexcept = 0;
};
struct FortyTwo: Plus2Base {
protected: /* Methods: */
int calculateValue() noexcept final override { return 40; }
};

Note that the friend keyword can be used to add access exceptions to functions or types for
accessing protected and private members.

The public, protected, and private keywords can also be used to grant or limit access to base
class subobjects. See the Inheritance example.

Inheritance

Classes/structs can have inheritance relations.

If a class/struct B inherits from a class/struct A, this means that B has as a parent A. We say that B is
a derived class/struct from A, and A is the base class/struct.

struct A
{
public:
int p1;
protected:
int p2;
private:
int p3;
};

//Make B inherit publicly (default) from A


struct B : A
{
};

There are 3 forms of inheritance for a class/struct:

• public
• private

https://riptutorial.com/ 96
• protected

Note that the default inheritance is the same as the default visibility of members: public if you use
the struct keyword, and private for the class keyword.

It's even possible to have a class derive from a struct (or vice versa). In this case, the default
inheritance is controlled by the child, so a struct that derives from a class will default to public
inheritance, and a class that derives from a struct will have private inheritance by default.

public inheritance:

struct B : public A // or just `struct B : A`


{
void foo()
{
p1 = 0; //well formed, p1 is public in B
p2 = 0; //well formed, p2 is protected in B
p3 = 0; //ill formed, p3 is private in A
}
};

B b;
b.p1 = 1; //well formed, p1 is public
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

private inheritance:

struct B : private A
{
void foo()
{
p1 = 0; //well formed, p1 is private in B
p2 = 0; //well formed, p2 is private in B
p3 = 0; //ill formed, p3 is private in A
}
};

B b;
b.p1 = 1; //ill formed, p1 is private
b.p2 = 1; //ill formed, p2 is private
b.p3 = 1; //ill formed, p3 is inaccessible

protected inheritance:

struct B : protected A
{
void foo()
{
p1 = 0; //well formed, p1 is protected in B
p2 = 0; //well formed, p2 is protected in B
p3 = 0; //ill formed, p3 is private in A
}
};

B b;

https://riptutorial.com/ 97
b.p1 = 1; //ill formed, p1 is protected
b.p2 = 1; //ill formed, p2 is protected
b.p3 = 1; //ill formed, p3 is inaccessible

Note that although protected inheritance is allowed, the actual use of it is rare. One instance of
how protected inheritance is used in application is in partial base class specialization (usually
referred to as "controlled polymorphism").

When OOP was relatively new, (public) inheritance was frequently said to model an "IS-A"
relationship. That is, public inheritance is correct only if an instance of the derived class is also an
instance of the base class.

This was later refined into the Liskov Substitution Principle: public inheritance should only be used
when/if an instance of the derived class can be substituted for an instance of the base class under
any possible circumstance (and still make sense).

Private inheritance is typically said to embody a completely different relationship: "is implemented
in terms of" (sometimes called a "HAS-A" relationship). For example, a Stack class could inherit
privately from a Vector class. Private inheritance bears a much greater similarity to aggregation
than to public inheritance.

Protected inheritance is almost never used, and there's no general agreement on what sort of
relationship it embodies.

Virtual Inheritance

When using inheritance, you can specify the virtual keyword:

struct A{};
struct B: public virtual A{};

When class B has virtual base A it means that A will reside in most derived class of inheritance
tree, and thus that most derived class is also responsible for initializing that virtual base:

struct A
{
int member;
A(int param)
{
member = param;
}
};

struct B: virtual A
{
B(): A(5){}
};

struct C: B
{
C(): /*A(88)*/ {}
};

https://riptutorial.com/ 98
void f()
{
C object; //error since C is not initializing it's indirect virtual base `A`
}

If we un-comment /*A(88)*/ we won't get any error since C is now initializing it's indirect virtual
base A.

Also note that when we're creating variable object, most derived class is C, so C is responsible for
creating(calling constructor of) A and thus value of A::member is 88, not 5 (as it would be if we were
creating object of type B).

It is useful when solving the diamond problem.:

A A A
/ \ | |
B C B C
\ / \ /
D D
virtual inheritance normal inheritance

B and C both inherit from A, and D inherits from B and C, so there are 2 instances of A in D! This
results in ambiguity when you're accessing member of A through D, as the compiler has no way of
knowing from which class do you want to access that member (the one which B inherits, or the one
that is inherited byC?).

Virtual inheritance solves this problem: Since virtual base resides only in most derived object,
there will be only one instance of A in D.

struct A
{
void foo() {}
};

struct B : public /*virtual*/ A {};


struct C : public /*virtual*/ A {};

struct D : public B, public C


{
void bar()
{
foo(); //Error, which foo? B::foo() or C::foo()? - Ambiguous
}
};

Removing the comments resolves the ambiguity.

Multiple Inheritance

Aside from single inheritance:

class A {};

https://riptutorial.com/ 99
class B : public A {};

You can also have multiple inheritance:

class A {};
class B {};
class C : public A, public B {};

C will now have inherit from A and B at the same time.

Note: this can lead to ambiguity if the same names are used in multiple inherited classs or
structs. Be careful!

Ambiguity in Multiple Inheritance

Multiple inheritance may be helpful in certain cases but, sometimes odd sort of problem
encounters while using multiple inheritance.

For example: Two base classes have functions with same name which is not overridden in derived
class and if you write code to access that function using object of derived class, compiler shows
error because, it cannot determine which function to call. Here is a code for this type of ambiguity
in multiple inheritance.

class base1
{
public:
void funtion( )
{ //code for base1 function }
};
class base2
{
void function( )
{ // code for base2 function }
};

class derived : public base1, public base2


{

};

int main()
{
derived obj;

// Error because compiler can't figure out which function to call


//either function( ) of base1 or base2 .
obj.function( )
}

But, this problem can be solved using scope resolution function to specify which function to class
either base1 or base2:

int main()
{

https://riptutorial.com/ 100
obj.base1::function( ); // Function of class base1 is called.
obj.base2::function( ); // Function of class base2 is called.
}

Accessing class members

To access member variables and member functions of an object of a class, the . operator is used:

struct SomeStruct {
int a;
int b;
void foo() {}
};

SomeStruct var;
// Accessing member variable a in var.
std::cout << var.a << std::endl;
// Assigning member variable b in var.
var.b = 1;
// Calling a member function.
var.foo();

When accessing the members of a class via a pointer, the -> operator is commonly used.
Alternatively, the instance can be dereferenced and the . operator used, although this is less
common:

struct SomeStruct {
int a;
int b;
void foo() {}
};

SomeStruct var;
SomeStruct *p = &var;
// Accessing member variable a in var via pointer.
std::cout << p->a << std::endl;
std::cout << (*p).a << std::endl;
// Assigning member variable b in var via pointer.
p->b = 1;
(*p).b = 1;
// Calling a member function via a pointer.
p->foo();
(*p).foo();

When accessing static class members, the :: operator is used, but on the name of the class
instead of an instance of it. Alternatively, the static member can be accessed from an instance or a
pointer to an instance using the . or -> operator, respectively, with the same syntax as accessing
non-static members.

struct SomeStruct {
int a;
int b;
void foo() {}

static int c;

https://riptutorial.com/ 101
static void bar() {}
};
int SomeStruct::c;

SomeStruct var;
SomeStruct* p = &var;
// Assigning static member variable c in struct SomeStruct.
SomeStruct::c = 5;
// Accessing static member variable c in struct SomeStruct, through var and p.
var.a = var.c;
var.b = p->c;
// Calling a static member function.
SomeStruct::bar();
var.bar();
p->bar();

Background
The -> operator is needed because the member access operator . has precedence over the
dereferencing operator *.

One would expect that *p.a would dereference p (resulting in a reference to the object p is pointing
to) and then accessing its member a. But in fact, it tries to access the member a of p and then
dereference it. I.e. *p.a is equivalent to *(p.a). In the example above, this would result in a
compiler error because of two facts: First, p is a pointer and does not have a member a. Second, a
is an integer and, thus, can't be dereferenced.

The uncommonly used solution to this problem would be to explicitly control the precedence:
(*p).a

Instead, the -> operator is almost always used. It is a short-hand for first dereferencing the pointer
and then accessing it. I.e. (*p).a is exactly the same as p->a.

The :: operator is the scope operator, used in the same manner as accessing a member of a
namespace. This is because a static class member is considered to be in that class' scope, but
isn't considered a member of instances of that class. The use of normal . and -> is also allowed
for static members, despite them not being instance members, for historical reasons; this is of use
for writing generic code in templates, as the caller doesn't need to be concerned with whether a
given member function is static or non-static.

Private inheritance: restricting base class interface

Private inheritance is useful when it is required to restrict the public interface of the class:

class A {
public:
int move();
int turn();
};

class B : private A {
public:

https://riptutorial.com/ 102
using A::turn;
};

B b;
b.move(); // compile error
b.turn(); // OK

This approach efficiently prevents an access to the A public methods by casting to the A pointer or
reference:

B b;
A& a = static_cast<A&>(b); // compile error

In the case of public inheritance such casting will provide access to all the A public methods
despite on alternative ways to prevent this in derived B, like hiding:

class B : public A {
private:
int move();
};

or private using:

class B : public A {
private:
using A::move;
};

then for both cases it is possible:

B b;
A& a = static_cast<A&>(b); // OK for public inheritance
a.move(); // OK

Final classes and structs

C++11

Deriving a class may be forbidden with final specifier. Let's declare a final class:

class A final {
};

Now any attempt to subclass it will cause a compilation error:

// Compilation error: cannot derive from final class:


class B : public A {
};

Final class may appear anywhere in class hierarchy:

https://riptutorial.com/ 103
class A {
};

// OK.
class B final : public A {
};

// Compilation error: cannot derive from final class B.


class C : public B {
};

Friendship

The friend keyword is used to give other classes and functions access to private and protected
members of the class, even through they are defined outside the class`s scope.

class Animal{
private:
double weight;
double height;
public:
friend void printWeight(Animal animal);
friend class AnimalPrinter;
// A common use for a friend function is to overload the operator<< for streaming.
friend std::ostream& operator<<(std::ostream& os, Animal animal);
};

void printWeight(Animal animal)


{
std::cout << animal.weight << "\n";
}

class AnimalPrinter
{
public:
void print(const Animal& animal)
{
// Because of the `friend class AnimalPrinter;" declaration, we are
// allowed to access private members here.
std::cout << animal.weight << ", " << animal.height << std::endl;
}
}

std::ostream& operator<<(std::ostream& os, Animal animal)


{
os << "Animal height: " << animal.height << "\n";
return os;
}

int main() {
Animal animal = {10, 5};
printWeight(animal);

AnimalPrinter aPrinter;
aPrinter.print(animal);

std::cout << animal;


}

https://riptutorial.com/ 104
10
10, 5
Animal height: 5

Nested Classes/Structures

A class or struct can also contain another class/struct definition inside itself, which is called a
"nested class"; in this situation, the containing class is referred to as the "enclosing class". The
nested class definition is considered to be a member of the enclosing class, but is otherwise
separate.

struct Outer {
struct Inner { };
};

From outside of the enclosing class, nested classes are accessed using the scope operator. From
inside the enclosing class, however, nested classes can be used without qualifiers:

struct Outer {
struct Inner { };

Inner in;
};

// ...

Outer o;
Outer::Inner i = o.in;

As with a non-nested class/struct, member functions and static variables can be defined either
within a nested class, or in the enclosing namespace. However, they cannot be defined within the
enclosing class, due to it being considered to be a different class than the nested class.

// Bad.
struct Outer {
struct Inner {
void do_something();
};

void Inner::do_something() {}
};

// Good.
struct Outer {
struct Inner {
void do_something();
};

};

void Outer::Inner::do_something() {}

As with non-nested classes, nested classes can be forward declared and defined later, provided

https://riptutorial.com/ 105
they are defined before being used directly.

class Outer {
class Inner1;
class Inner2;

class Inner1 {};

Inner1 in1;
Inner2* in2p;

public:
Outer();
~Outer();
};

class Outer::Inner2 {};

Outer::Outer() : in1(Inner1()), in2p(new Inner2) {}


Outer::~Outer() {
if (in2p) { delete in2p; }
}

C++11

Prior to C++11, nested classes only had access to type names, static members, and enumerators
from the enclosing class; all other members defined in the enclosing class were off-limits.

C++11

As of C++11, nested classes, and members thereof, are treated as if they were friends of the
enclosing class, and can access all of its members, according to the usual access rules; if
members of the nested class require the ability to evaluate one or more non-static members of the
enclosing class, they must therefore be passed an instance:

class Outer {
struct Inner {
int get_sizeof_x() {
return sizeof(x); // Legal (C++11): x is unevaluated, so no instance is required.
}

int get_x() {
return x; // Illegal: Can't access non-static member without an instance.
}

int get_x(Outer& o) {
return o.x; // Legal (C++11): As a member of Outer, Inner can access private
members.
}
};

int x;
};

Conversely, the enclosing class is not treated as a friend of the nested class, and thus cannot
access its private members without explicitly being granted permission.

https://riptutorial.com/ 106
class Outer {
class Inner {
// friend class Outer;

int x;
};

Inner in;

public:
int get_x() {
return in.x; // Error: int Outer::Inner::x is private.
// Uncomment "friend" line above to fix.
}
};

Friends of a nested class are not automatically considered friends of the enclosing class; if they
need to be friends of the enclosing class as well, this must be declared separately. Conversely, as
the enclosing class is not automatically considered a friend of the nested class, neither will friends
of the enclosing class be considered friends of the nested class.

class Outer {
friend void barge_out(Outer& out, Inner& in);

class Inner {
friend void barge_in(Outer& out, Inner& in);

int i;
};

int o;
};

void barge_in(Outer& out, Outer::Inner& in) {


int i = in.i; // Good.
int o = out.o; // Error: int Outer::o is private.
}

void barge_out(Outer& out, Outer::Inner& in) {


int i = in.i; // Error: int Outer::Inner::i is private.
int o = out.o; // Good.
}

As with all other class members, nested classes can only be named from outside the class if they
have public access. However, you are allowed to access them regardless of access modifier, as
long as you don't explicitly name them.

class Outer {
struct Inner {
void func() { std::cout << "I have no private taboo.\n"; }
};

public:
static Inner make_Inner() { return Inner(); }
};

https://riptutorial.com/ 107
// ...

Outer::Inner oi; // Error: Outer::Inner is private.

auto oi = Outer::make_Inner(); // Good.


oi.func(); // Good.
Outer::make_Inner().func(); // Good.

You can also create a type alias for a nested class. If a type alias is contained in the enclosing
class, the nested type and the type alias can have different access modifiers. If the type alias is
outside the enclosing class, it requires that either the nested class, or a typedef thereof, be public.

class Outer {
class Inner_ {};

public:
typedef Inner_ Inner;
};

typedef Outer::Inner ImOut; // Good.


typedef Outer::Inner_ ImBad; // Error.

// ...

Outer::Inner oi; // Good.


Outer::Inner_ oi; // Error.
ImOut oi; // Good.

As with other classes, nested classes can both derive from or be derived from by other classes.

struct Base {};

struct Outer {
struct Inner : Base {};
};

struct Derived : Outer::Inner {};

This can be useful in situations where the enclosing class is derived from by another class, by
allowing the programmer to update the nested class as necessary. This can be combined with a
typedef to provide a consistent name for each enclosing class' nested class:

class BaseOuter {
struct BaseInner_ {
virtual void do_something() {}
virtual void do_something_else();
} b_in;

public:
typedef BaseInner_ Inner;

virtual ~BaseOuter() = default;

virtual Inner& getInner() { return b_in; }


};

https://riptutorial.com/ 108
void BaseOuter::BaseInner_::do_something_else() {}

// ---

class DerivedOuter : public BaseOuter {


// Note the use of the qualified typedef; BaseOuter::BaseInner_ is private.
struct DerivedInner_ : BaseOuter::Inner {
void do_something() override {}
void do_something_else() override;
} d_in;

public:
typedef DerivedInner_ Inner;

BaseOuter::Inner& getInner() override { return d_in; }


};

void DerivedOuter::DerivedInner_::do_something_else() {}

// ...

// Calls BaseOuter::BaseInner_::do_something();
BaseOuter* b = new BaseOuter;
BaseOuter::Inner& bin = b->getInner();
bin.do_something();
b->getInner().do_something();

// Calls DerivedOuter::DerivedInner_::do_something();
BaseOuter* d = new DerivedOuter;
BaseOuter::Inner& din = d->getInner();
din.do_something();
d->getInner().do_something();

In the above case, both BaseOuter and DerivedOuter supply the member type Inner, as BaseInner_
and DerivedInner_, respectively. This allows nested types to be derived without breaking the
enclosing class' interface, and allows the nested type to be used polymorphically.

Member Types and Aliases

A class or struct can also define member type aliases, which are type aliases contained within,
and treated as members of, the class itself.

struct IHaveATypedef {
typedef int MyTypedef;
};

struct IHaveATemplateTypedef {
template<typename T>
using MyTemplateTypedef = std::vector<T>;
};

Like static members, these typedefs are accessed using the scope operator, ::.

IHaveATypedef::MyTypedef i = 5; // i is an int.

https://riptutorial.com/ 109
IHaveATemplateTypedef::MyTemplateTypedef<int> v; // v is a std::vector<int>.

As with normal type aliases, each member type alias is allowed to refer to any type defined or
aliased before, but not after, its definition. Likewise, a typedef outside the class definition can refer
to any accessible typedefs within the class definition, provided it comes after the class definition.

template<typename T>
struct Helper {
T get() const { return static_cast<T>(42); }
};

struct IHaveTypedefs {
// typedef MyTypedef NonLinearTypedef; // Error if uncommented.
typedef int MyTypedef;
typedef Helper<MyTypedef> MyTypedefHelper;
};

IHaveTypedefs::MyTypedef i; // x_i is an int.


IHaveTypedefs::MyTypedefHelper hi; // x_hi is a Helper<int>.

typedef IHaveTypedefs::MyTypedef TypedefBeFree;


TypedefBeFree ii; // ii is an int.

Member type aliases can be declared with any access level, and will respect the appropriate
access modifier.

class TypedefAccessLevels {
typedef int PrvInt;

protected:
typedef int ProInt;

public:
typedef int PubInt;
};

TypedefAccessLevels::PrvInt prv_i; // Error: TypedefAccessLevels::PrvInt is private.


TypedefAccessLevels::ProInt pro_i; // Error: TypedefAccessLevels::ProInt is protected.
TypedefAccessLevels::PubInt pub_i; // Good.

class Derived : public TypedefAccessLevels {


PrvInt prv_i; // Error: TypedefAccessLevels::PrvInt is private.
ProInt pro_i; // Good.
PubInt pub_i; // Good.
};

This can be used to provide a level of abstraction, allowing a class' designer to change its internal
workings without breaking code that relies on it.

class Something {
friend class SomeComplexType;

short s;
// ...

https://riptutorial.com/ 110
public:
typedef SomeComplexType MyHelper;

MyHelper get_helper() const { return MyHelper(8, s, 19.5, "shoe", false); }

// ...
};

// ...

Something s;
Something::MyHelper hlp = s.get_helper();

In this situation, if the helper class is changed from SomeComplexType to some other type, only the
typedef and the friend declaration would need to be modified; as long as the helper class provides
the same functionality, any code that uses it as Something::MyHelper instead of specifying it by
name will usually still work without any modifications. In this manner, we minimise the amount of
code that needs to be modified when the underlying implementation is changed, such that the type
name only needs to be changed in one location.

This can also be combined with decltype, if one so desires.

class SomethingElse {
AnotherComplexType<bool, int, SomeThirdClass> helper;

public:
typedef decltype(helper) MyHelper;

private:
InternalVariable<MyHelper> ivh;

// ...

public:
MyHelper& get_helper() const { return helper; }

// ...
};

In this situation, changing the implementation of SomethingElse::helper will automatically change


the typedef for us, due to decltype. This minimises the number of modifications necessary when
we want to change helper, which minimises the risk of human error.

As with everything, however, this can be taken too far. If the typename is only used once or twice
internally and zero times externally, for example, there's no need to provide an alias for it. If it's
used hundreds or thousands of times throughout a project, or if it has a long enough name, then it
can be useful to provide it as a typedef instead of always using it in absolute terms. One must
balance forwards compatibility and convenience with the amount of unnecessary noise created.

This can also be used with template classes, to provide access to the template parameters from
outside the class.

template<typename T>

https://riptutorial.com/ 111
class SomeClass {
// ...

public:
typedef T MyParam;
MyParam getParam() { return static_cast<T>(42); }
};

template<typename T>
typename T::MyParam some_func(T& t) {
return t.getParam();
}

SomeClass<int> si;
int i = some_func(si);

This is commonly used with containers, which will usually provide their element type, and other
helper types, as member type aliases. Most of the containers in the C++ standard library, for
example, provide the following 12 helper types, along with any other special types they might
need.

template<typename T>
class SomeContainer {
// ...

public:
// Let's provide the same helper types as most standard containers.
typedef T value_type;
typedef std::allocator<value_type> allocator_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef MyIterator<value_type> iterator;
typedef MyConstIterator<value_type> const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
};

Prior to C++11, it was also commonly used to provide a "template typedef" of sorts, as the feature
wasn't yet available; these have become a bit less common with the introduction of alias
templates, but are still useful in some situations (and are combined with alias templates in other
situations, which can be very useful for obtaining individual components of a complex type such as
a function pointer). They commonly use the name type for their type alias.

template<typename T>
struct TemplateTypedef {
typedef T type;
}

TemplateTypedef<int>::type i; // i is an int.

This was often used with types with multiple template parameters, to provide an alias that defines

https://riptutorial.com/ 112
one or more of the parameters.

template<typename T, size_t SZ, size_t D>


class Array { /* ... */ };

template<typename T, size_t SZ>


struct OneDArray {
typedef Array<T, SZ, 1> type;
};

template<typename T, size_t SZ>


struct TwoDArray {
typedef Array<T, SZ, 2> type;
};

template<typename T>
struct MonoDisplayLine {
typedef Array<T, 80, 1> type;
};

OneDArray<int, 3>::type arr1i; // arr1i is an Array<int, 3, 1>.


TwoDArray<short, 5>::type arr2s; // arr2s is an Array<short, 5, 2>.
MonoDisplayLine<char>::type arr3c; // arr3c is an Array<char, 80, 1>.

Static class members

A class is also allowed to have static members, which can be either variables or functions. These
are considered to be in the class' scope, but aren't treated as normal members; they have static
storage duration (they exist from the start of the program to the end), aren't tied to a particular
instance of the class, and only one copy exists for the entire class.

class Example {
static int num_instances; // Static data member (static member variable).
int i; // Non-static member variable.

public:
static std::string static_str; // Static data member (static member variable).
static int static_func(); // Static member function.

// Non-static member functions can modify static member variables.


Example() { ++num_instances; }
void set_str(const std::string& str);
};

int Example::num_instances;
std::string Example::static_str = "Hello.";

// ...

Example one, two, three;


// Each Example has its own "i", such that:
// (&one.i != &two.i)
// (&one.i != &three.i)
// (&two.i != &three.i).
// All three Examples share "num_instances", such that:
// (&one.num_instances == &two.num_instances)
// (&one.num_instances == &three.num_instances)

https://riptutorial.com/ 113
// (&two.num_instances == &three.num_instances)

Static member variables are not considered to be defined inside the class, only declared, and thus
have their definition outside the class definition; the programmer is allowed, but not required, to
initialise static variables in their definition. When defining the member variables, the keyword
static is omitted.

class Example {
static int num_instances; // Declaration.

public:
static std::string static_str; // Declaration.

// ...
};

int Example::num_instances; // Definition. Zero-initialised.


std::string Example::static_str = "Hello."; // Definition.

Due to this, static variables can be incomplete types (apart from void), as long as they're later
defined as a complete type.

struct ForwardDeclared;

class ExIncomplete {
static ForwardDeclared fd;
static ExIncomplete i_contain_myself;
static int an_array[];
};

struct ForwardDeclared {};

ForwardDeclared ExIncomplete::fd;
ExIncomplete ExIncomplete::i_contain_myself;
int ExIncomplete::an_array[5];

Static member functions can be defined inside or outside the class definition, as with normal
member functions. As with static member variables, the keyword static is omitted when defining
static member functions outside the class definition.

// For Example above, either...


class Example {
// ...

public:
static int static_func() { return num_instances; }

// ...

void set_str(const std::string& str) { static_str = str; }


};

// Or...

class Example { /* ... */ };

https://riptutorial.com/ 114
int Example::static_func() { return num_instances; }
void Example::set_str(const std::string& str) { static_str = str; }

If a static member variable is declared const but not volatile, and is of an integral or enumeration
type, it can be initialised at declaration, inside the class definition.

enum E { VAL = 5 };

struct ExConst {
const static int ci = 5; // Good.
static const E ce = VAL; // Good.
const static double cd = 5; // Error.
static const volatile int cvi = 5; // Error.

const static double good_cd;


static const volatile int good_cvi;
};

const double ExConst::good_cd = 5; // Good.


const volatile int ExConst::good_cvi = 5; // Good.

C++11

As of C++11, static member variables of LiteralType types (types that can be constructed at
compile time, according to constexpr rules) can also be declared as constexpr; if so, they must be
initialised within the class definition.

struct ExConstexpr {
constexpr static int ci = 5; // Good.
static constexpr double cd = 5; // Good.
constexpr static int carr[] = { 1, 1, 2 }; // Good.
static constexpr ConstexprConstructibleClass c{}; // Good.
constexpr static int bad_ci; // Error.
};

constexpr int ExConstexpr::bad_ci = 5; // Still an error.

If a const or constexpr static member variable is odr-used (informally, if it has its address taken or
is assigned to a reference), then it must still have a separate definition, outside the class definition.
This definition is not allowed to contain an initialiser.

struct ExODR {
static const int odr_used = 5;
};

// const int ExODR::odr_used;

const int* odr_user = & ExODR::odr_used; // Error; uncomment above line to resolve.

As static members aren't tied to a given instance, they can be accessed using the scope operator,
::.

https://riptutorial.com/ 115
std::string str = Example::static_str;

They can also be accessed as if they were normal, non-static members. This is of historical
significance, but is used less commonly than the scope operator to prevent confusion over
whether a member is static or non-static.

Example ex;
std::string rts = ex.static_str;

Class members are able to access static members without qualifying their scope, as with non-
static class members.

class ExTwo {
static int num_instances;
int my_num;

public:
ExTwo() : my_num(num_instances++) {}

static int get_total_instances() { return num_instances; }


int get_instance_number() const { return my_num; }
};

int ExTwo::num_instances;

They cannot be mutable, nor would they need to be; as they aren't tied to any given instance,
whether an instance is or isn't const doesn't affect static members.

struct ExDontNeedMutable {
int immuta;
mutable int muta;

static int i;

ExDontNeedMutable() : immuta(-5), muta(-5) {}


};
int ExDontNeedMutable::i;

// ...

const ExDontNeedMutable dnm;


dnm.immuta = 5; // Error: Can't modify read-only object.
dnm.muta = 5; // Good. Mutable fields of const objects can be written.
dnm.i = 5; // Good. Static members can be written regardless of an instance's const-
ness.

Static members respect access modifiers, just like non-static members.

class ExAccess {
static int prv_int;

protected:
static int pro_int;

https://riptutorial.com/ 116
public:
static int pub_int;
};

int ExAccess::prv_int;
int ExAccess::pro_int;
int ExAccess::pub_int;

// ...

int x1 = ExAccess::prv_int; // Error: int ExAccess::prv_int is private.


int x2 = ExAccess::pro_int; // Error: int ExAccess::pro_int is protected.
int x3 = ExAccess::pub_int; // Good.

As they aren't tied to a given instance, static member functions have no this pointer; due to this,
they can't access non-static member variables unless passed an instance.

class ExInstanceRequired {
int i;

public:
ExInstanceRequired() : i(0) {}

static void bad_mutate() { ++i *= 5; } // Error.


static void good_mutate(ExInstanceRequired& e) { ++e.i *= 5; } // Good.
};

Due to not having a this pointer, their addresses can't be stored in pointers-to-member-functions,
and are instead stored in normal pointers-to-functions.

struct ExPointer {
void nsfunc() {}
static void sfunc() {}
};

typedef void (ExPointer::* mem_f_ptr)();


typedef void (*f_ptr)();

mem_f_ptr p_sf = &ExPointer::sfunc; // Error.


f_ptr p_sf = &ExPointer::sfunc; // Good.

Due to not having a this pointer, they also cannot be const or volatile, nor can they have ref-
qualifiers. They also cannot be virtual.

struct ExCVQualifiersAndVirtual {
static void func() {} // Good.
static void cfunc() const {} // Error.
static void vfunc() volatile {} // Error.
static void cvfunc() const volatile {} // Error.
static void rfunc() & {} // Error.
static void rvfunc() && {} // Error.

virtual static void vsfunc() {} // Error.


static virtual void svfunc() {} // Error.

https://riptutorial.com/ 117
};

As they aren't tied to a given instance, static member variables are effectively treated as special
global variables; they're created when the program starts, and destroyed when it exits, regardless
of whether any instances of the class actually exist. Only a single copy of each static member
variable exists (unless the variable is declared thread_local (C++11 or later), in which case there's
one copy per thread).

Static member variables have the same linkage as the class, whether the class has external or
internal linkage. Local classes and unnamed classes aren't allowed to have static members.

Non-static member functions

A class can have non-static member functions, which operate on individual instances of the class.

class CL {
public:
void member_function() {}
};

These functions are called on an instance of the class, like so:

CL instance;
instance.member_function();

They can be defined either inside or outside the class definition; if defined outside, they are
specified as being in the class' scope.

struct ST {
void defined_inside() {}
void defined_outside();
};
void ST::defined_outside() {}

They can be CV-qualified and/or ref-qualified, affecting how they see the instance they're called
upon; the function will see the instance as having the specified cv-qualifier(s), if any. Which
version is called will be based on the instance's cv-qualifiers. If there is no version with the same
cv-qualifiers as the instance, then a more-cv-qualified version will be called if available.

struct CVQualifiers {
void func() {} // 1: Instance is non-cv-qualified.
void func() const {} // 2: Instance is const.

void cv_only() const volatile {}


};

CVQualifiers non_cv_instance;
const CVQualifiers c_instance;

non_cv_instance.func(); // Calls #1.


c_instance.func(); // Calls #2.

https://riptutorial.com/ 118
non_cv_instance.cv_only(); // Calls const volatile version.
c_instance.cv_only(); // Calls const volatile version.

C++11

Member function ref-qualifiers indicate whether or not the function is intended to be called on
rvalue instances, and use the same syntax as function cv-qualifiers.

struct RefQualifiers {
void func() & {} // 1: Called on normal instances.
void func() && {} // 2: Called on rvalue (temporary) instances.
};

RefQualifiers rf;
rf.func(); // Calls #1.
RefQualifiers{}.func(); // Calls #2.

CV-qualifiers and ref-qualifiers can also be combined if necessary.

struct BothCVAndRef {
void func() const& {} // Called on normal instances. Sees instance as const.
void func() && {} // Called on temporary instances.
};

They can also be virtual; this is fundamental to polymorphism, and allows a child class(es) to
provide the same interface as the parent class, while supplying their own functionality.

struct Base {
virtual void func() {}
};
struct Derived {
virtual void func() {}
};

Base* bp = new Base;


Base* dp = new Derived;
bp.func(); // Calls Base::func().
dp.func(); // Calls Derived::func().

For more information, see here.

Unnamed struct/class

Unnamed struct is allowed (type has no name)

void foo()
{
struct /* No name */ {
float x;
float y;
} point;

point.x = 42;

https://riptutorial.com/ 119
}

or

struct Circle
{
struct /* No name */ {
float x;
float y;
} center; // but a member name
float radius;
};

and later

Circle circle;
circle.center.x = 42.f;

but NOT anonymous struct (unnamed type and unnamed object)

struct InvalidCircle
{
struct /* No name */ {
float centerX;
float centerY;
}; // No member either.
float radius;
};

Note: Some compilers allow anonymous struct as extension.

C++11

• lamdba can be seen as a special unnamed struct.

• decltype allows to retrieve the type of unnamed struct:

decltype(circle.point) otherPoint;

• unnamed struct instance can be parameter of template method:

void print_square_coordinates()
{
const struct {float x; float y;} points[] = {
{-1, -1}, {-1, 1}, {1, -1}, {1, 1}
};

// for range relies on `template <class T, std::size_t N> std::begin(T (&)[N])`


for (const auto& point : points) {
std::cout << "{" << point.x << ", " << point.y << "}\n";
}

decltype(points[0]) topRightCorner{1, 1};

https://riptutorial.com/ 120
auto it = std::find(points, points + 4, topRightCorner);
std::cout << "top right corner is the "
<< 1 + std::distance(points, it) << "th\n";
}

Read Classes/Structures online: https://riptutorial.com/cplusplus/topic/508/classes-structures

https://riptutorial.com/ 121
Chapter 23: Client server examples
Examples
Hello TCP Server

Let me start by saying you should first visit Beej's Guide to Network Programming and give it a
quick read, which explains most of this stuff a bit more verbosely. We'll be creating a simple TCP
server here which will say "Hello World" to all incoming connections and then close them. Another
thing to note is, the server will be communicating to clients iteratively, which means one client at a
time. Make sure to check out relevant man pages as they might contain valuable information about
each function call and socket structures.

We'll run the server with a port, so we'll take an argument for port number as well. Let's get started
with code -

#include <cstring> // sizeof()


#include <iostream>
#include <string>

// headers for socket(), getaddrinfo() and friends


#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>

#include <unistd.h> // close()

int main(int argc, char *argv[])


{
// Let's check if port number is supplied or not..
if (argc != 2) {
std::cerr << "Run program as 'program <port>'\n";
return -1;
}

auto &portNum = argv[1];


const unsigned int backLog = 8; // number of connections allowed on the incoming queue

addrinfo hints, *res, *p; // we need 2 pointers, res to hold and p to iterate over
memset(&hints, 0, sizeof(hints));

// for more explanation, man socket


hints.ai_family = AF_UNSPEC; // don't specify which IP version to use yet
hints.ai_socktype = SOCK_STREAM; // SOCK_STREAM refers to TCP, SOCK_DGRAM will be?
hints.ai_flags = AI_PASSIVE;

// man getaddrinfo
int gAddRes = getaddrinfo(NULL, portNum, &hints, &res);
if (gAddRes != 0) {
std::cerr << gai_strerror(gAddRes) << "\n";

https://riptutorial.com/ 122
return -2;
}

std::cout << "Detecting addresses" << std::endl;

unsigned int numOfAddr = 0;


char ipStr[INET6_ADDRSTRLEN]; // ipv6 length makes sure both ipv4/6 addresses can be
stored in this variable

// Now since getaddrinfo() has given us a list of addresses


// we're going to iterate over them and ask user to choose one
// address for program to bind to
for (p = res; p != NULL; p = p->ai_next) {
void *addr;
std::string ipVer;

// if address is ipv4 address


if (p->ai_family == AF_INET) {
ipVer = "IPv4";
sockaddr_in *ipv4 = reinterpret_cast<sockaddr_in *>(p->ai_addr);
addr = &(ipv4->sin_addr);
++numOfAddr;
}

// if address is ipv6 address


else {
ipVer = "IPv6";
sockaddr_in6 *ipv6 = reinterpret_cast<sockaddr_in6 *>(p->ai_addr);
addr = &(ipv6->sin6_addr);
++numOfAddr;
}

// convert IPv4 and IPv6 addresses from binary to text form


inet_ntop(p->ai_family, addr, ipStr, sizeof(ipStr));
std::cout << "(" << numOfAddr << ") " << ipVer << " : " << ipStr
<< std::endl;
}

// if no addresses found :(
if (!numOfAddr) {
std::cerr << "Found no host address to use\n";
return -3;
}

// ask user to choose an address


std::cout << "Enter the number of host address to bind with: ";
unsigned int choice = 0;
bool madeChoice = false;
do {
std::cin >> choice;
if (choice > (numOfAddr + 1) || choice < 1) {
madeChoice = false;
std::cout << "Wrong choice, try again!" << std::endl;
} else
madeChoice = true;
} while (!madeChoice);

p = res;

https://riptutorial.com/ 123
// let's create a new socket, socketFD is returned as descriptor
// man socket for more information
// these calls usually return -1 as result of some error
int sockFD = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockFD == -1) {
std::cerr << "Error while creating socket\n";
freeaddrinfo(res);
return -4;
}

// Let's bind address to our socket we've just created


int bindR = bind(sockFD, p->ai_addr, p->ai_addrlen);
if (bindR == -1) {
std::cerr << "Error while binding socket\n";

// if some error occurs, make sure to close socket and free resources
close(sockFD);
freeaddrinfo(res);
return -5;
}

// finally start listening for connections on our socket


int listenR = listen(sockFD, backLog);
if (listenR == -1) {
std::cerr << "Error while Listening on socket\n";

// if some error occurs, make sure to close socket and free resources
close(sockFD);
freeaddrinfo(res);
return -6;
}

// structure large enough to hold client's address


sockaddr_storage client_addr;
socklen_t client_addr_size = sizeof(client_addr);

const std::string response = "Hello World";

// a fresh infinite loop to communicate with incoming connections


// this will take client connections one at a time
// in further examples, we're going to use fork() call for each client connection
while (1) {

// accept call will give us a new socket descriptor


int newFD
= accept(sockFD, (sockaddr *) &client_addr, &client_addr_size);
if (newFD == -1) {
std::cerr << "Error while Accepting on socket\n";
continue;
}

// send call sends the data you specify as second param and it's length as 3rd param,
also returns how many bytes were actually sent
auto bytes_sent = send(newFD, response.data(), response.length(), 0);
close(newFD);

https://riptutorial.com/ 124
}

close(sockFD);
freeaddrinfo(res);

return 0;
}

The following program runs as -

Detecting addresses
(1) IPv4 : 0.0.0.0
(2) IPv6 : ::
Enter the number of host address to bind with: 1

Hello TCP Client

This program is complimentary to Hello TCP Server program, you can run either of them to check
the validity of each other. The program flow is quite common with Hello TCP server, so make sure
to take a look at that too.

Here's the code -

#include <cstring>
#include <iostream>
#include <string>

#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char *argv[])


{
// Now we're taking an ipaddress and a port number as arguments to our program
if (argc != 3) {
std::cerr << "Run program as 'program <ipaddress> <port>'\n";
return -1;
}

auto &ipAddress = argv[1];


auto &portNum = argv[2];

addrinfo hints, *p;


memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

int gAddRes = getaddrinfo(ipAddress, portNum, &hints, &p);


if (gAddRes != 0) {
std::cerr << gai_strerror(gAddRes) << "\n";
return -2;
}

https://riptutorial.com/ 125
if (p == NULL) {
std::cerr << "No addresses found\n";
return -3;
}

// socket() call creates a new socket and returns it's descriptor


int sockFD = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockFD == -1) {
std::cerr << "Error while creating socket\n";
return -4;
}

// Note: there is no bind() call as there was in Hello TCP Server


// why? well you could call it though it's not necessary
// because client doesn't necessarily has to have a fixed port number
// so next call will bind it to a random available port number

// connect() call tries to establish a TCP connection to the specified server


int connectR = connect(sockFD, p->ai_addr, p->ai_addrlen);
if (connectR == -1) {
close(sockFD);
std::cerr << "Error while connecting socket\n";
return -5;
}

std::string reply(15, ' ');

// recv() call tries to get the response from server


// BUT there's a catch here, the response might take multiple calls
// to recv() before it is completely received
// will be demonstrated in another example to keep this minimal
auto bytes_recv = recv(sockFD, &reply.front(), reply.size(), 0);
if (bytes_recv == -1) {
std::cerr << "Error while receiving bytes\n";
return -6;
}

std::cout << "\nClient recieved: " << reply << std::endl;


close(sockFD);
freeaddrinfo(p);

return 0;
}

Read Client server examples online: https://riptutorial.com/cplusplus/topic/7177/client-server-


examples

https://riptutorial.com/ 126
Chapter 24: Common compile/linker errors
(GCC)
Examples
error: '***' was not declared in this scope

This error happens if a unknown object is used.

Variables
Not compiling:

#include <iostream>

int main(int argc, char *argv[])


{
{
int i = 2;
}

std::cout << i << std::endl; // i is not in the scope of the main function

return 0;
}

Fix:

#include <iostream>

int main(int argc, char *argv[])


{
{
int i = 2;
std::cout << i << std::endl;
}

return 0;
}

Functions
Most of the time this error occurs if the needed header is not included (e.g. using
std::cout without #include <iostream>)

Not compiling:

#include <iostream>

https://riptutorial.com/ 127
int main(int argc, char *argv[])
{
doCompile();

return 0;
}

void doCompile()
{
std::cout << "No!" << std::endl;
}

Fix:

#include <iostream>

void doCompile(); // forward declare the function

int main(int argc, char *argv[])


{
doCompile();

return 0;
}

void doCompile()
{
std::cout << "No!" << std::endl;
}

Or:

#include <iostream>

void doCompile() // define the function before using it


{
std::cout << "No!" << std::endl;
}

int main(int argc, char *argv[])


{
doCompile();

return 0;
}

Note: The compiler interprets the code from top to bottom (simplification). Everything must be at
least declared (or defined) before usage.

undefined reference to `***'

This linker error happens, if the linker can't find a used symbol. Most of the time, this happens if a
used library is not linked against.

qmake:

https://riptutorial.com/ 128
LIBS += nameOfLib

cmake:

TARGET_LINK_LIBRARIES(target nameOfLib)

g++ call:

g++ -o main main.cpp -Llibrary/dir -lnameOfLib

One might also forget to compile and link all used .cpp files (functionsModule.cpp defines the
needed function):

g++ -o binName main.o functionsModule.o

fatal error: ***: No such file or directory

The compiler can't find a file (a source file uses #include "someFile.hpp").

qmake:

INCLUDEPATH += dir/Of/File

cmake:

include_directories(dir/Of/File)

g++ call:

g++ -o main main.cpp -Idir/Of/File

Read Common compile/linker errors (GCC) online:


https://riptutorial.com/cplusplus/topic/4256/common-compile-linker-errors--gcc-

https://riptutorial.com/ 129
Chapter 25: Compiling and Building
Introduction
Programs written in C++ need to be compiled before they can be run. There is a large variety of
compilers available depending on your operating system.

Remarks
Most operating systems ship without a compiler, and they have to be installed later. Some
common compilers choices are:

• GCC, the GNU Compiler Collection g++


• clang: a C language family frontend for LLVM clang++
• MSVC, Microsoft Visual C++ (included in Visual Studio) visual-c++
• C++Builder, Embarcadero C++Builder (included in RAD Studio) c++builder

Please consult the appropriate compiler manual, on how to compile a C++ program.

Another option to use a specific compiler with its own specific build system, it is possible to let
generic build systems configure the project for a specific compiler or for the default installed one.

Examples
Compiling with GCC

Assuming a single source file named main.cpp, the command to compile and link an non-optimized
executable is as follows (Compiling without optimization is useful for initial development and
debugging, although -Og is officially recommended for newer GCC versions).

g++ -o app -Wall main.cpp -O0

To produce an optimized executable for use in production, use one of the -O options (see: -O1, -O2,
-O3, -Os, -Ofast):

g++ -o app -Wall -O2 main.cpp

If the -O option is omitted, -O0, which means no optimizations, is used as default (specifying -O
without a number resolves to -O1).

Alternatively, use optimization flags from the O groups (or more experimental optimizations)
directly. The following example builds with -O2 optimization, plus one flag from the -O3 optimization
level:

g++ -o app -Wall -O2 -ftree-partial-pre main.cpp

https://riptutorial.com/ 130
To produce a platform-specific optimized executable (for use in production on the machine with
the same architecture), use:

g++ -o app -Wall -O2 -march=native main.cpp

Either of the above will produce a binary file that can be run with .\app.exe on Windows and ./app
on Linux, Mac OS, etc.

The -o flag can also be skipped. In this case, GCC will create default output executable a.exe on
Windows and a.out on Unix-like systems. To compile a file without linking it, use the -c option:

g++ -o file.o -Wall -c file.cpp

This produces an object file named file.o which can later be linked with other files to produce a
binary:

g++ -o app file.o otherfile.o

More about optimization options can be found at gcc.gnu.org. Of particular note are -Og
(optimization with an emphasis on debugging experience -- recommended for the standard edit-
compile-debug cycle) and -Ofast (all optimizations, including ones disregarding strict standards
compliance).

The -Wall flag enables warnings for many common errors and should always be used. To improve
code quality it is often encouraged also to use -Wextra and other warning flags which are not
automatically enabled by -Wall and -Wextra.

If the code expects a specific C++ standard, specify which standard to use by including the -std=
flag. Supported values correspond to the year of finalization for each version of the ISO C++
standard. As of GCC 6.1.0, valid values for the std= flag are c++98/c++03, c++11, c++14, and c++17/
c++1z. Values separated by a forward slash are equivalent.

g++ -std=c++11 <file>

GCC includes some compiler-specific extensions that are disabled when they conflict with a
standard specified by the -std= flag. To compile with all extensions enabled, the value gnu++XX may
be used, where XX is any of the years used by the c++ values listed above.

The default standard will be used if none is specified. For versions of GCC prior to 6.1.0, the
default is -std=gnu++03; in GCC 6.1.0 and greater, the default is -std=gnu++14.

Note that due to bugs in GCC, the -pthread flag must be present at compilation and linking for
GCC to support the C++ standard threading functionality introduced with C++11, such as
std::thread and std::wait_for. Omitting it when using threading functions may result in no
warnings but invalid results on some platforms.

https://riptutorial.com/ 131
Linking with libraries:
Use the -l option to pass the library name:

g++ main.cpp -lpcre2-8


#pcre2-8 is the PCRE2 library for 8bit code units (UTF-8)

If the library is not in the standard library path, add the path with -L option:

g++ main.cpp -L/my/custom/path/ -lmylib

Multiple libraries can be linked together:

g++ main.cpp -lmylib1 -lmylib2 -lmylib3

If one library depends on another, put the dependent library before the independent library:

g++ main.cpp -lchild-lib -lbase-lib

Or let the linker determine the ordering itself via --start-group and --end-group (note: this has
significant performance cost):

g++ main.cpp -Wl,--start-group -lbase-lib -lchild-lib -Wl,--end-group

Compiling with Visual C++ (Command Line)

For programmers coming from GCC or Clang to Visual Studio, or programmers more comfortable
with the command line in general, you can use the Visual C++ compiler from the command line as
well as the IDE.

If you desire to compile your code from the command line in Visual Studio, you first need to set up
the command line environment. This can be done either by opening the Visual Studio Command
Prompt/Developer Command Prompt/x86 Native Tools Command Prompt/x64 Native Tools Command Prompt or
similar (as provided by your version of Visual Studio), or at the command prompt, by navigating to
the VC subdirectory of the compiler's install directory (typically \Program Files (x86)\Microsoft
Visual Studio x\VC, where x is the version number (such as 10.0 for 2010, or 14.0 for 2015) and
running the VCVARSALL batch file with a command-line parameter specified here.

Note that unlike GCC, Visual Studio doesn't provide a front-end for the linker (link.exe) via the
compiler (cl.exe), but instead provides the linker as a separate program, which the compiler calls
as it exits. cl.exe and link.exe can be used separately with different files and options, or cl can be
told to pass files and options to link if both tasks are done together. Any linking options specified
to cl will be translated into options for link, and any files not processed by cl will be passed
directly to link. As this is mainly a simple guide to compiling with the Visual Studio command line,
arguments for link will not be described at this time; if you need a list, see here.

https://riptutorial.com/ 132
Note that arguments to cl are case-sensitive, while arguments to link are not.

[Be advised that some of the following examples use the Windows shell "current directory"
variable, %cd%, when specifying absolute path names. For anyone unfamiliar with this variable, it
expands to the current working directory. From the command line, it will be the directory you were
in when you ran cl, and is specified in the command prompt by default (if your command prompt is
C:\src>, for example, then %cd% is C:\src\).]

Assuming a single source file named main.cpp in the current folder, the command to compile and
link an unoptimised executable (useful for initial development and debugging) is (use either of the
following):

cl main.cpp
// Generates object file "main.obj".
// Performs linking with "main.obj".
// Generates executable "main.exe".

cl /Od main.cpp
// Same as above.
// "/Od" is the "Optimisation: disabled" option, and is the default when no /O is specified.

Assuming an additional source file "niam.cpp" in the same directory, use the following:

cl main.cpp niam.cpp
// Generates object files "main.obj" and "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

You can also use wildcards, as one would expect:

cl main.cpp src\*.cpp
// Generates object file "main.obj", plus one object file for each ".cpp" file in folder
// "%cd%\src".
// Performs linking with "main.obj", and every additional object file generated.
// All object files will be in the current folder.
// Generates executable "main.exe".

To rename or relocate the executable, use one of the following:

cl /o name main.cpp
// Generates executable named "name.exe".

cl /o folder\ main.cpp
// Generates executable named "main.exe", in folder "%cd%\folder".

cl /o folder\name main.cpp
// Generates executable named "name.exe", in folder "%cd%\folder".

cl /Fename main.cpp
// Same as "/o name".

cl /Fefolder\ main.cpp
// Same as "/o folder\".

https://riptutorial.com/ 133
cl /Fefolder\name main.cpp
// Same as "/o folder\name".

Both /o and /Fe pass their parameter (let's call it o-param) to link as /OUT:o-param, appending the
appropriate extension (generally .exe or .dll) to "name" o-params as necessary. While both /o and
/Fe are to my knowledge identical in functionality, the latter is preferred for Visual Studio. /o is
marked as deprecated, and appears to mainly be provided for programmers more familiar with
GCC or Clang.

Note that while the space between /o and the specified folder and/or name is optional, there
cannot be a space between /Fe and the specified folder and/or name.

Similarly, to produce an optimised executable (for use in production), use:

cl /O1 main.cpp
// Optimise for executable size. Produces small programs, at the possible expense of slower
// execution.

cl /O2 main.cpp
// Optimise for execution speed. Produces fast programs, at the possible expense of larger
// file size.

cl /GL main.cpp other.cpp


// Generates special object files used for whole-program optimisation, which allows CL to
// take every module (translation unit) into consideration during optimisation.
// Passes the option "/LTCG" (Link-Time Code Generation) to LINK, telling it to call CL during
// the linking phase to perform additional optimisations. If linking is not performed at
this
// time, the generated object files should be linked with "/LTCG".
// Can be used with other CL optimisation options.

Finally, to produce a platform-specific optimized executable (for use in production on the machine
with the specified architecture), choose the appropriate command prompt or VCVARSALL parameter
for the target platform. link should detect the desired platform from the object files; if not, use the
/MACHINE option to explicitly specify the target platform.

// If compiling for x64, and LINK doesn't automatically detect target platform:
cl main.cpp /link /machine:X64

Any of the above will produce an executable with the name specified by /o or /Fe, or if neither is
provided, with a name identical to the first source or object file specified to the compiler.

cl a.cpp b.cpp c.cpp


// Generates "a.exe".

cl d.obj a.cpp q.cpp


// Generates "d.exe".

cl y.lib n.cpp o.obj


// Generates "n.exe".

https://riptutorial.com/ 134
cl /o yo zp.obj pz.cpp
// Generates "yo.exe".

To compile a file(s) without linking, use:

cl /c main.cpp
// Generates object file "main.obj".

This tells cl to exit without calling link, and produces an object file, which can later be linked with
other files to produce a binary.

cl main.obj niam.cpp
// Generates object file "niam.obj".
// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

link main.obj niam.obj


// Performs linking with "main.obj" and "niam.obj".
// Generates executable "main.exe".

There are other valuable command line parameters as well, which it would be very useful for users
to know:

cl /EHsc main.cpp
// "/EHsc" specifies that only standard C++ ("synchronous") exceptions will be caught,
// and `extern "C"` functions will not throw exceptions.
// This is recommended when writing portable, platform-independent code.

cl /clr main.cpp
// "/clr" specifies that the code should be compiled to use the common language runtime,
// the .NET Framework's virtual machine.
// Enables the use of Microsoft's C++/CLI language in addition to standard ("native") C++,
// and creates an executable that requires .NET to run.

cl /Za main.cpp
// "/Za" specifies that Microsoft extensions should be disabled, and code should be
// compiled strictly according to ISO C++ specifications.
// This is recommended for guaranteeing portability.

cl /Zi main.cpp
// "/Zi" generates a program database (PDB) file for use when debugging a program, without
// affecting optimisation specifications, and passes the option "/DEBUG" to LINK.

cl /LD dll.cpp
// "/LD" tells CL to configure LINK to generate a DLL instead of an executable.
// LINK will output a DLL, in addition to an LIB and EXP file for use when linking.
// To use the DLL in other programs, pass its associated LIB to CL or LINK when compiling
those
// programs.

cl main.cpp /link /LINKER_OPTION


// "/link" passes everything following it directly to LINK, without parsing it in any way.
// Replace "/LINKER_OPTION" with any desired LINK option(s).

https://riptutorial.com/ 135
For anyone more familiar with *nix systems and/or GCC/Clang, cl, link, and other Visual Studio
command line tools can accept parameters specified with a hyphen (such as -c) instead of a slash
(such as /c). Additionally, Windows recognises either a slash or a backslash as a valid path
separator, so *nix-style paths can be used as well. This makes it easy to convert simple compiler
command lines from g++ or clang++ to cl, or vice versa, with minimal changes.

g++ -o app src/main.cpp


cl -o app src/main.cpp

Of course, when porting command lines that use more complex g++ or clang++ options, you need to
look up equivalent commands in the applicable compiler documentations and/or on resource sites,
but this makes it easier to get things started with minimal time spent learning about new compilers.

In case you need specific language features for your code, a specific release of MSVC was
required. From Visual C++ 2015 Update 3 on it is possible to choose the version of the standard to
compile with via the /std flag. Possible values are /std:c++14 and /std:c++latest (/std:c++17 will
follow soon).

Note: In older versions of this compiler, specific feature flags were available however this was
mostly used for previews of new features.

Compiling with Visual Studio (Graphical Interface) - Hello World

1. Download and install Visual Studio Community 2015


2. Open Visual Studio Community
3. Click File -> New -> Project

4. Click Templates -> Visual C++ -> Win32 Console Application and then name the project
MyFirstProgram.

https://riptutorial.com/ 136
5. Click Ok
6. Click Next in the following window.

https://riptutorial.com/ 137
7. Check the Empty project box and then click Finish:

https://riptutorial.com/ 138
8. Right click on folder Source File then -> Add --> New Item :

https://riptutorial.com/ 139
9. Select C++ File and name the file main.cpp, then click Add:

https://riptutorial.com/ 140
10: Copy and paste the following code in the new file main.cpp:

#include <iostream>

int main()
{
std::cout << "Hello World!\n";
return 0;
}

You environment should look like:

https://riptutorial.com/ 141
11. Click Debug -> Start Without Debugging (or press ctrl + F5) :

12. Done. You should get the following console output :

https://riptutorial.com/ 142
Compiling with Clang

As the Clang front-end is designed for being compatible with GCC, most programs that can be
compiled via GCC will compile when you swap g++ by clang++ in the build scripts. If no -std=version
is given, gnu11 will be used.

Windows users who are used to MSVC can swap cl.exe with clang-cl.exe. By default, clang tries
to be compatible with the highest version of MSVC that has been installed.

In the case of compiling with visual studio, clang-cl can be used by changing the Platform toolset
in the project properties.

In both cases, clang is only compatible via its front-end, though it also tries to generate binary
compatible object files. Users of clang-cl should note that the compatibility with MSVC is not
complete yet.

To use clang or clang-cl, one could use the default installation on certain Linux distributions or
those bundled with IDEs (like XCode on Mac). For other versions of this compiler or on platforms
which don't have this installed, this can be download from the official download page.

If you're using CMake to build your code you can usually switch the compiler by setting the CC and
CXX environment variables like this:

mkdir build
cd build
CC=clang CXX=clang++ cmake ..
cmake --build .

See also introduction to Cmake.

Online Compilers

https://riptutorial.com/ 143
Various websites provide online access to C++ compilers. Online compiler's feature set vary
significantly from site to site, but usually they allow to do the following:

• Paste your code into a web form in the browser.


• Select some compiler options and compile the code.
• Collect compiler and/or program output.

Online compiler website behavior is usually quite restrictive as they allow anyone to run compilers
and execute arbitrary code on their server side, whereas ordinarily remote arbitrary code
execution is considered as vulnerability.

Online compilers may be useful for the following purposes:

• Run a small code snippet from a machine which lacks C++ compiler (smartphones, tablets,
etc.).
• Ensure that code compiles successfully with different compilers and runs the same way
regardless the compiler it was compiled with.
• Learn or teach basics of C++.
• Learn modern C++ features (C++14 and C++17 in near future) when up-to-date C++
compiler is not available on local machine.
• Spot a bug in your compiler by comparison with a large set of other compilers. Check if a
compiler bug was fixed in future versions, which are unavailable on your machine.
• Solve online judge problems.

What online compilers should not be used for:

• Develop full-featured (even small) applications using C++. Usually online compilers do not
allow to link with third-party libraries or download build artifacts.
• Perform intensive computations. Sever-side computing resources are limited, so any user-
provided program will be killed after a few seconds of execution. The permitted execution
time is usually enough for testing and learning.
• Attack compiler server itself or any third-party hosts on the net.

Examples:

Disclaimer: documentation author(s) are not affiliated with any resources listed below.
Websites are listed alphabetically.

• http://codepad.org/ Online compiler with code sharing. Editing code after compiling with a
source code warning or error does not work so well.
• http://coliru.stacked-crooked.com/ Online compiler for which you specify the command line.
Provides both GCC and Clang compilers for use.
• http://cpp.sh/ - Online compiler with C++14 support. Does not allow you to edit compiler
command line, but some options are available via GUI controls.
• https://gcc.godbolt.org/ - Provides a wide list of compiler versions, architectures, and
disassembly output. Very useful when you need to inspect what your code compiles into by
different compilers. GCC, Clang, MSVC (CL), Intel compiler (icc), ELLCC, and Zapcc are
present, with one or more of these compilers available for the ARM, ARMv8 (as ARM64),

https://riptutorial.com/ 144
Atmel AVR, MIPS, MIPS64, MSP430, PowerPC, x86, and x64 architecutres. Compiler
command line arguments may be edited.
• https://ideone.com/ - Widely used on the Net to illustrate code snippet behavior. Provides
both GCC and Clang for use, but doesn't allow you to edit the compiler command line.
• http://melpon.org/wandbox - Supports numerous Clang and GNU/GCC compiler versions.
• http://onlinegdb.com/ - An extremely minimalistic IDE that includes an editor, a compiler
(gcc), and a debugger (gdb).
• http://rextester.com/ - Provides Clang, GCC, and Visual Studio compilers for both C and C++
(along with compilers for other languages), with the Boost library available for use.
• http://tutorialspoint.com/compile_cpp11_online.php - Full-featured UNIX shell with GCC, and
a user-friendly project explorer.
• http://webcompiler.cloudapp.net/ - Online Visual Studio 2015 compiler, provided by Microsoft
as part of RiSE4fun.

The C++ compilation process

When you develop a C++ program, the next step is to compile the program before running it. The
compilation is the process which converts the program written in human readable language like C,
C++ etc into a machine code, directly understood by the Central Processing Unit. For example, if
you have a C++ source code file named prog.cpp and you execute the compile command,

g++ -Wall -ansi -o prog prog.cpp

There are 4 main stages involved in creating an executable file from the source file.

1. The C++ the preprocessor takes a C++ source code file and deals with the
headers(#include), macros(#define) and other preprocessor directives.

2. The expanded C++ source code file produced by the C++ preprocessor is compiled into the
assembly language for the platform.

3. The assembler code generated by the compiler is assembled into the object code for the
platform.

4. The object code file produced by the assembler is linked together


with the object code files for any library functions used to produce either a library or an
executable file.

Preprocessing

The preprocessor handles the preprocessor directives, like #include and #define. It is agnostic of
the syntax of C++, which is why it must be used with care.

It works on one C++ source file at a time by replacing #include directives with the content of the
respective files (which is usually just declarations), doing replacement of macros (#define), and
selecting different portions of text depending of #if, #ifdef and #ifndef directives.

The preprocessor works on a stream of preprocessing tokens. Macro substitution is defined as

https://riptutorial.com/ 145
replacing tokens with other tokens (the operator ## enables merging two tokens when it make
sense).

After all this, the preprocessor produces a single output that is a stream of tokens resulting from
the transformations described above. It also adds some special markers that tell the compiler
where each line came from so that it can use those to produce sensible error messages.

Some errors can be produced at this stage with clever use of the #if and #error directives.

By using below compiler flag, we can stop the process at preprocessing stage.

g++ -E prog.cpp

Compilation

The compilation step is performed on each output of the preprocessor. The compiler parses the
pure C++ source code (now without any preprocessor directives) and converts it into assembly
code. Then invokes underlying back-end(assembler in toolchain) that assembles that code into
machine code producing actual binary file in some format(ELF, COFF, a.out, ...). This object file
contains the compiled code (in binary form) of the symbols defined in the input. Symbols in object
files are referred to by name.

Object files can refer to symbols that are not defined. This is the case when you use a declaration,
and don't provide a definition for it. The compiler doesn't mind this, and will happily produce the
object file as long as the source code is well-formed.

Compilers usually let you stop compilation at this point. This is very useful because with it you can
compile each source code file separately. The advantage this provides is that you don't need to
recompile everything if you only change a single file.

The produced object files can be put in special archives called static libraries, for easier reusing
later on.

It's at this stage that "regular" compiler errors, like syntax errors or failed overload resolution
errors, are reported.

In order to stop the process after the compile step, we can use the -S option:

g++ -Wall -ansi -S prog.cpp

Assembling

The assembler creates object code. On a UNIX system you may see files with a .o suffix (.OBJ on
MSDOS) to indicate object code files. In this phase the assembler converts those object files from
assembly code into machine level instructions and the file created is a relocatable object code.
Hence, the compilation phase generates the relocatable object program and this program can be
used in different places without having to compile again.

To stop the process after the assembly step, you can use the -c option:

https://riptutorial.com/ 146
g++ -Wall -ansi -c prog.cpp

Linking

The linker is what produces the final compilation output from the object files the assembler
produced. This output can be either a shared (or dynamic) library (and while the name is similar,
they don't have much in common with static libraries mentioned earlier) or an executable.

It links all the object files by replacing the references to undefined symbols with the correct
addresses. Each of these symbols can be defined in other object files or in libraries. If they are
defined in libraries other than the standard library, you need to tell the linker about them.

At this stage the most common errors are missing definitions or duplicate definitions. The former
means that either the definitions don't exist (i.e. they are not written), or that the object files or
libraries where they reside were not given to the linker. The latter is obvious: the same symbol was
defined in two different object files or libraries.

Compiling with Code::Blocks (Graphical interface)

1. Download and install Code::Blocks here. If you're on Windows, be careful to select a file for
which the name contains mingw, the other files don't install any compiler.

2. Open Code::Blocks and click on "Create a new project":

https://riptutorial.com/ 147
https://riptutorial.com/ 148
3. Select "Console application" and click "Go":

4. Click "Next", select "C++", click "Next", select a name for your project and choose a folder to
save it in, click "Next" and then click "Finish".

5. Now you can edit and compile your code. A default code that prints "Hello world!" in the
console is already there. To compile and/or run your program, press one of the three
compile/run buttons in the toolbar:

https://riptutorial.com/ 149
https://riptutorial.com/ 150
To compile without running, press , to run without compiling again, press and to
compile and then run, press .

and to compile and then run, press .

and to compile and then run, press .

Compiling and running the default "Hello world!" code gives the following result:

Read Compiling and Building online: https://riptutorial.com/cplusplus/topic/4708/compiling-and-

https://riptutorial.com/ 151
building

https://riptutorial.com/ 152
Chapter 26: Concurrency With OpenMP
Introduction
This topic covers the basics of concurrency in C++ using OpenMP. OpenMP is documented in
more detail in the OpenMP tag.

Parallelism or concurrency implies the execution of code at the same time.

Remarks
OpenMP does not require any special headers or libraries as it is a built-in compiler feature.
However, if you use any OpenMP API functions such as omp_get_thread_num(), you will need to
include omp.h and its library.

OpenMP pragma statements are ignored when the OpenMP option is not enabled during
compilation. You may want to refer to the compiler option in your compiler's manual.

• GCC uses -fopenmp


• Clang uses -fopenmp
• MSVC uses /openmp

Examples
OpenMP: Parallel Sections

This example illustrates the basics of executing sections of code in parallel.

As OpenMP is a built-in compiler feature, it works on any supported compilers without including
any libraries. You may wish to include omp.h if you want to use any of the openMP API features.

Sample Code

std::cout << "begin ";


// This pragma statement hints the compiler that the
// contents within the { } are to be executed in as
// parallel sections using openMP, the compiler will
// generate this chunk of code for parallel execution
#pragma omp parallel sections
{
// This pragma statement hints the compiler that
// this is a section that can be executed in parallel
// with other section, a single section will be executed
// by a single thread.
// Note that it is "section" as opposed to "sections" above
#pragma omp section
{
std::cout << "hello " << std::endl;
/** Do something **/

https://riptutorial.com/ 153
}
#pragma omp section
{
std::cout << "world " << std::endl;
/** Do something **/
}
}
// This line will not be executed until all the
// sections defined above terminates
std::cout << "end" << std::endl;

Outputs

This example produces 2 possible outputs and is dependent on the operating system and
hardware. The output also illustrates a race condition problem that would occur from such an
implementation.

OUTPUT A OUTPUT B

begin hello world end begin world hello end

OpenMP: Parallel Sections

This example shows how to execute chunks of code in parallel

std::cout << "begin ";


// Start of parallel sections
#pragma omp parallel sections
{
// Execute these sections in parallel
#pragma omp section
{
... do something ...
std::cout << "hello ";
}
#pragma omp section
{
... do something ...
std::cout << "world ";
}
#pragma omp section
{
... do something ...
std::cout << "forever ";
}
}
// end of parallel sections
std::cout << "end";

Output

• begin hello world forever end


• begin world hello forever end
• begin hello forever world end

https://riptutorial.com/ 154
• begin forever hello world end

As execution order is not guaranteed, you may observe any of the above output.

OpenMP: Parallel For Loop

This example shows how to divide a loop into equal parts and execute them in parallel.

// Splits element vector into element.size() / Thread Qty


// and allocate that range for each thread.
#pragma omp parallel for
for (size_t i = 0; i < element.size(); ++i)
element[i] = ...

// Example Allocation (100 element per thread)


// Thread 1 : 0 ~ 99
// Thread 2 : 100 ~ 199
// Thread 2 : 200 ~ 299
// ...

// Continue process
// Only when all threads completed their allocated
// loop job
...

*Please take extra care to not modify the size of the vector used in parallel for loops as allocated
range indices doesn't update automatically.

OpenMP: Parallel Gathering / Reduction

This example illustrates a concept to perform reduction or gathering using std::vector and
OpenMP.

Supposed we have a scenario where we want multiple threads to help us generate a bunch of
stuff, int is used here for simplicity and can be replaced with other data types.

This is particularly useful when you need to merge results from slaves to avoid segement faults or
memory access violations and do not wish to use libraries or custom sync container libraries.

// The Master vector


// We want a vector of results gathered from slave threads
std::vector<int> Master;

// Hint the compiler to parallelize this { } of code


// with all available threads (usually the same as logical processor qty)
#pragma omp parallel
{
// In this area, you can write any code you want for each
// slave thread, in this case a vector to hold each of their results
// We don't have to worry about how many threads were spawn or if we need
// to repeat this declaration or not.
std::vector<int> Slave;

// Tell the compiler to use all threads allocated for this parallel region
// to perform this loop in parts. Actual load appx = 1000000 / Thread Qty

https://riptutorial.com/ 155
// The nowait keyword tells the compiler that the slave threads don't
// have to wait for all other slaves to finish this for loop job
#pragma omp for nowait
for (size_t i = 0; i < 1000000; ++i
{
/* Do something */
....
Slave.push_back(...);
}

// Slaves that finished their part of the job


// will perform this thread by thread one at a time
// critical section ensures that only 0 or 1 thread performs
// the { } at any time
#pragma omp critical
{
// Merge slave into master
// use move iterators instead, avoid copy unless
// you want to use it for something else after this section
Master.insert(Master.end(),
std::make_move_iterator(Slave.begin()),
std::make_move_iterator(Slave.end()));
}
}

// Have fun with Master vector


...

Read Concurrency With OpenMP online: https://riptutorial.com/cplusplus/topic/8222/concurrency-


with-openmp

https://riptutorial.com/ 156
Chapter 27: Const Correctness
Syntax
• class ClassOne { public: bool non_modifying_member_function() const { /* ... */ } };
• int ClassTwo::non_modifying_member_function() const { /* ... */ }
• void ClassTwo::modifying_member_function() { /* ... */ }
• char non_param_modding_func(const ClassOne& one, const ClassTwo* two) { /* ... */ }
• float parameter_modifying_function(ClassTwo& one, ClassOne* two) { /* ... */ }
• short ClassThree::non_modding_non_param_modding_f(const ClassOne&) const { /* ... */ }

Remarks
const correctness is a very useful troubleshooting tool, as it allows the programmer to quickly
determine which functions might be inadvertently modifying code. It also prevents unintentional
errors, such as the one shown in Const Correct Function Parameters, from compiling properly and
going unnoticed.

It is much easier to design a class for const correctness, than it is to later add const correctness to
a pre-existing class. If possible, design any class that can be const correct so that it is const
correct, to save yourself and others the hassle of later modifying it.

Note that this can also be applied to volatile correctness if necessary, with the same rules as for
const correctness, but this is used much less often.

Refrences :

ISO_CPP

Sell me on const correctness

C++ Tutorial

Examples
The Basics

const correctness is the practice of designing code so that only code that needs to modify an
instance is able to modify an instance (i.e. has write access), and conversely, that any code that
doesn't need to modify an instance is unable to do so (i.e. only has read access). This prevents
the instance from being modified unintentionally, making code less errorprone, and documents
whether the code is intended to change the instance's state or not. It also allows instances to be
treated as const whenever they don't need to be modified, or defined as const if they don't need to
be changed after initialisation, without losing any functionality.

https://riptutorial.com/ 157
This is done by giving member functions const CV-qualifiers, and by making pointer/reference
parameters const, except in the case that they need write access.

class ConstCorrectClass {
int x;

public:
int getX() const { return x; } // Function is const: Doesn't modify instance.
void setX(int i) { x = i; } // Not const: Modifies instance.
};

// Parameter is const: Doesn't modify parameter.


int const_correct_reader(const ConstCorrectClass& c) {
return c.getX();
}

// Parameter isn't const: Modifies parameter.


void const_correct_writer(ConstCorrectClass& c) {
c.setX(42);
}

const ConstCorrectClass invariant; // Instance is const: Can't be modified.


ConstCorrectClass variant; // Instance isn't const: Can be modified.

// ...

const_correct_reader(invariant); // Good. Calling non-modifying function on const instance.


const_correct_reader(variant); // Good. Calling non-modifying function on modifiable
instance.

const_correct_writer(variant); // Good. Calling modifying function on modifiable instance.


const_correct_writer(invariant); // Error. Calling modifying function on const instance.

Due to the nature of const correctness, this starts with the class' member functions, and works its
way outwards; if you try to call a non-const member function from a const instance, or from a non-
const instance being treated as const, the compiler will give you an error about it losing cv-
qualifiers.

Const Correct Class Design

In a const-correct class, all member functions which don't change logical state have this cv-
qualified as const, indicating that they don't modify the object (apart from any mutable fields, which
can freely be modified even in const instances); if a const cv-qualified function returns a reference,
that reference should also be const. This allows them to be called on both constant and non-cv-
qualified instances, as a const T* is capable of binding to either a T* or a const T*. This, in turn,
allows functions to declare their passed-by-reference parameters as const when they don't need to
be modified, without losing any functionality.

Furthermore, in a const correct class, all passed-by-reference function parameters will be const
correct, as discussed in Const Correct Function Parameters, so that they can only be modified when
the function explicitly needs to modify them.

First, let's look at this cv-qualifiers:

https://riptutorial.com/ 158
// Assume class Field, with member function "void insert_value(int);".

class ConstIncorrect {
Field fld;

public:
ConstIncorrect(Field& f); // Modifies.

Field& getField(); // Might modify. Also exposes member as non-const reference,


// allowing indirect modification.
void setField(Field& f); // Modifies.

void doSomething(int i); // Might modify.


void doNothing(); // Might modify.
};

ConstIncorrect::ConstIncorrect(Field& f) : fld(f) {} // Modifies.


Field& ConstIncorrect::getField() { return fld; } // Doesn't modify.
void ConstIncorrect::setField(Field& f) { fld = f; } // Modifies.
void ConstIncorrect::doSomething(int i) { // Modifies.
fld.insert_value(i);
}
void ConstIncorrect::doNothing() {} // Doesn't modify.

class ConstCorrectCVQ {
Field fld;

public:
ConstCorrectCVQ(Field& f); // Modifies.

const Field& getField() const; // Doesn't modify. Exposes member as const reference,
// preventing indirect modification.
void setField(Field& f); // Modifies.

void doSomething(int i); // Modifies.


void doNothing() const; // Doesn't modify.
};

ConstCorrectCVQ::ConstCorrectCVQ(Field& f) : fld(f) {}
Field& ConstCorrectCVQ::getField() const { return fld; }
void ConstCorrectCVQ::setField(Field& f) { fld = f; }
void ConstCorrectCVQ::doSomething(int i) {
fld.insert_value(i);
}
void ConstCorrectCVQ::doNothing() const {}

// This won't work.


// No member functions can be called on const ConstIncorrect instances.
void const_correct_func(const ConstIncorrect& c) {
Field f = c.getField();
c.do_nothing();
}

// But this will.


// getField() and doNothing() can be called on const ConstCorrectCVQ instances.
void const_correct_func(const ConstCorrectCVQ& c) {
Field f = c.getField();
c.do_nothing();
}

https://riptutorial.com/ 159
We can then combine this with Const Correct Function Parameters, causing the class to be fully
const-correct.

class ConstCorrect {
Field fld;

public:
ConstCorrect(const Field& f); // Modifies instance. Doesn't modify parameter.

const Field& getField() const; // Doesn't modify. Exposes member as const reference,
// preventing indirect modification.
void setField(const Field& f); // Modifies instance. Doesn't modify parameter.

void doSomething(int i); // Modifies. Doesn't modify parameter (passed by value).


void doNothing() const; // Doesn't modify.
};

ConstCorrect::ConstCorrect(const Field& f) : fld(f) {}


Field& ConstCorrect::getField() const { return fld; }
void ConstCorrect::setField(const Field& f) { fld = f; }
void ConstCorrect::doSomething(int i) {
fld.insert_value(i);
}
void ConstCorrect::doNothing() const {}

This can also be combined with overloading based on constness, in the case that we want one
behaviour if the instance is const, and a different behaviour if it isn't; a common use for this is
constainers providing accessors that only allow modification if the container itself is non-const.

class ConstCorrectContainer {
int arr[5];

public:
// Subscript operator provides read access if instance is const, or read/write access
// otherwise.
int& operator[](size_t index) { return arr[index]; }
const int& operator[](size_t index) const { return arr[index]; }

// ...
};

This is commonly used in the standard library, with most containers providing overloads to take
constness into account.

Const Correct Function Parameters

In a const-correct function, all passed-by-reference parameters are marked as const unless the
function directly or indirectly modifies them, preventing the programmer from inadvertently
changing something they didn't mean to change. This allows the function to take both const and
non-cv-qualified instances, and in turn, causes the instance's this to be of type const T* when a
member function is called, where T is the class' type.

struct Example {

https://riptutorial.com/ 160
void func() { std::cout << 3 << std::endl; }
void func() const { std::cout << 5 << std::endl; }
};

void const_incorrect_function(Example& one, Example* two) {


one.func();
two->func();
}

void const_correct_function(const Example& one, const Example* two) {


one.func();
two->func();
}

int main() {
Example a, b;
const_incorrect_function(a, &b);
const_correct_function(a, &b);
}

// Output:
3
3
5
5

While the effects of this are less immediately visible than those of const correct class design (in
that const-correct functions and const-incorrect classes will cause compilation errors, while const-
correct classes and const-incorrect functions will compile properly), const correct functions will
catch a lot of errors that const incorrect functions would let slip through, such as the one below.
[Note, however, that a const-incorrect function will cause compilation errors if passed a const
instance when it expected a non-const one.]

// Read value from vector, then compute & return a value.


// Caches return values for speed.
template<typename T>
const T& bad_func(std::vector<T>& v, Helper<T>& h) {
// Cache values, for future use.
// Once a return value has been calculated, it's cached & its index is registered.
static std::vector<T> vals = {};

int v_ind = h.get_index(); // Current working index for v.


int vals_ind = h.get_cache_index(v_ind); // Will be -1 if cache index isn't registered.

if (vals.size() && (vals_ind != -1) && (vals_ind < vals.size()) && !(h.needs_recalc())) {
return vals[h.get_cache_index(v_ind)];
}

T temp = v[v_ind];

temp -= h.poll_device();
temp *= h.obtain_random();
temp += h.do_tedious_calculation(temp, v[h.get_last_handled_index()]);

// We're feeling tired all of a sudden, and this happens.


if (vals_ind != -1) {
vals[vals_ind] = temp;
} else {

https://riptutorial.com/ 161
v.push_back(temp); // Oops. Should've been accessing vals.
vals_ind = vals.size() - 1;
h.register_index(v_ind, vals_ind);
}

return vals[vals_ind];
}

// Const correct version. Is identical to above version, so most of it shall be skipped.


template<typename T>
const T& good_func(const std::vector<T>& v, Helper<T>& h) {
// ...

// We're feeling tired all of a sudden, and this happens.


if (vals_ind != -1) {
vals[vals_ind] = temp;
} else {
v.push_back(temp); // Error: discards qualifiers.
vals_ind = vals.size() - 1;
h.register_index(v_ind, vals_ind);
}

return vals[vals_ind];
}

Const Correctness as Documentation

One of the more useful things about const correctness is that it serves as a way of documenting
code, providing certain guarantees to the programmer and other users. These guarantees are
enforced by the compiler due to constness, with a lack of constness in turn indicating that code
doesn't provide them.

const CV-Qualified Member Functions:


• Any member function which is const can be assumed to have intent to read the instance,
and:
○Shall not modify the logical state of the instance they are called on. Therefore, they
shall not modify any member variables of the instance they are called on, except
mutable variables.
○Shall not call any other functions that would modify any member variables of the
instance, except mutable variables.
• Conversely, any member function which isn't const can be assumed to have intent to modify
the instance, and:
○May or may not modify logical state.
○May or may not call other functions which modify logical state.

This can be used to make assumptions about the state of the object after any given member
function is called, even without seeing the definition of that function:

// ConstMemberFunctions.h

class ConstMemberFunctions {

https://riptutorial.com/ 162
int val;
mutable int cache;
mutable bool state_changed;

public:
// Constructor clearly changes logical state. No assumptions necessary.
ConstMemberFunctions(int v = 0);

// We can assume this function doesn't change logical state, and doesn't call
// set_val(). It may or may not call squared_calc() or bad_func().
int calc() const;

// We can assume this function doesn't change logical state, and doesn't call
// set_val(). It may or may not call calc() or bad_func().
int squared_calc() const;

// We can assume this function doesn't change logical state, and doesn't call
// set_val(). It may or may not call calc() or squared_calc().
void bad_func() const;

// We can assume this function changes logical state, and may or may not call
// calc(), squared_calc(), or bad_func().
void set_val(int v);
};

Due to const rules, these assumptions will in fact be enforced by the compiler.

// ConstMemberFunctions.cpp

ConstMemberFunctions::ConstMemberFunctions(int v /* = 0*/)
: cache(0), val(v), state_changed(true) {}

// Our assumption was correct.


int ConstMemberFunctions::calc() const {
if (state_changed) {
cache = 3 * val;
state_changed = false;
}

return cache;
}

// Our assumption was correct.


int ConstMemberFunctions::squared_calc() const {
return calc() * calc();
}

// Our assumption was incorrect.


// Function fails to compile, due to `this` losing qualifiers.
void ConstMemberFunctions::bad_func() const {
set_val(863);
}

// Our assumption was correct.


void ConstMemberFunctions::set_val(int v) {
if (v != val) {
val = v;
state_changed = true;
}
}

https://riptutorial.com/ 163
const Function Parameters:
• Any function with one or more parameters which are const can be assumed to have intent to
read those parameters, and:
○Shall not modify those parameters, or call any member functions that would modify
them.
○Shall not pass those parameters to any other function which would modify them and/or
call any member functions that would modify them.
• Conversely, any function with one or more parameters which aren't const can be assumed to
have intent to modify those parameters, and:
○May or may not modify those parameters, or call any member functions which whould
modify them.
○May or may not pass those parameters to other functions which would modify them
and/or call any member functions that would modify them.

This can be used to make assumptions about the state of the parameters after being passed to
any given function, even without seeing the definition of that function.

// function_parameter.h

// We can assume that c isn't modified (and c.set_val() isn't called), and isn't passed
// to non_qualified_function_parameter(). If passed to one_const_one_not(), it is the first
// parameter.
void const_function_parameter(const ConstMemberFunctions& c);

// We can assume that c is modified and/or c.set_val() is called, and may or may not be passed
// to any of these functions. If passed to one_const_one_not, it may be either parameter.
void non_qualified_function_parameter(ConstMemberFunctions& c);

// We can assume that:


// l is not modified, and l.set_val() won't be called.
// l may or may not be passed to const_function_parameter().
// r is modified, and/or r.set_val() may be called.
// r may or may not be passed to either of the preceding functions.
void one_const_one_not(const ConstMemberFunctions& l, ConstMemberFunctions& r);

// We can assume that c isn't modified (and c.set_val() isn't called), and isn't passed
// to non_qualified_function_parameter(). If passed to one_const_one_not(), it is the first
// parameter.
void bad_parameter(const ConstMemberFunctions& c);

Due to const rules, these assumptions will in fact be enforced by the compiler.

// function_parameter.cpp

// Our assumption was correct.


void const_function_parameter(const ConstMemberFunctions& c) {
std::cout << "With the current value, the output is: " << c.calc() << '\n'
<< "If squared, it's: " << c.squared_calc()
<< std::endl;
}

// Our assumption was correct.


void non_qualified_function_parameter(ConstMemberFunctions& c) {

https://riptutorial.com/ 164
c.set_val(42);
std::cout << "For the value 42, the output is: " << c.calc() << '\n'
<< "If squared, it's: " << c.squared_calc()
<< std::endl;
}

// Our assumption was correct, in the ugliest possible way.


// Note that const correctness doesn't prevent encapsulation from intentionally being broken,
// it merely prevents code from having write access when it doesn't need it.
void one_const_one_not(const ConstMemberFunctions& l, ConstMemberFunctions& r) {
// Let's just punch access modifiers and common sense in the face here.
struct Machiavelli {
int val;
int unimportant;
bool state_changed;
};
reinterpret_cast<Machiavelli&>(r).val = l.calc();
reinterpret_cast<Machiavelli&>(r).state_changed = true;

const_function_parameter(l);
const_function_parameter(r);
}

// Our assumption was incorrect.


// Function fails to compile, due to `this` losing qualifiers in c.set_val().
void bad_parameter(const ConstMemberFunctions& c) {
c.set_val(18);
}

While it is possible to circumvent const correctness, and by extension break these guarantees, this
must be done intentionally by the programmer (just like breaking encapsulation with Machiavelli,
above), and is likely to cause undefined behaviour.

class DealBreaker : public ConstMemberFunctions {


public:
DealBreaker(int v = 0);

// A foreboding name, but it's const...


void no_guarantees() const;
}

DealBreaker::DealBreaker(int v /* = 0 */) : ConstMemberFunctions(v) {}

// Our assumption was incorrect.


// const_cast removes const-ness, making the compiler think we know what we're doing.
void DealBreaker::no_guarantees() const {
const_cast<DealBreaker*>(this)->set_val(823);
}

// ...

const DealBreaker d(50);


d.no_guarantees(); // Undefined behaviour: d really IS const, it may or may not be modified.

However, due to this requiring the programmer to very specifically tell the compiler that they intend
to ignore constness, and being inconsistent across compilers, it is generally safe to assume that
const correct code will refrain from doing so unless otherwise specified.

https://riptutorial.com/ 165
Read Const Correctness online: https://riptutorial.com/cplusplus/topic/7217/const-correctness

https://riptutorial.com/ 166
Chapter 28: const keyword
Syntax
• const Type myVariable = initial; // Declares a const variable; cannot be changed
• const Type &myReference = myVariable; // Declares a reference to a const variable
• const Type *myPointer = &myVariable; // Declares a pointer-to-const. The pointer can
change, but the underlying data member cannot be changed through the pointer
• Type * const myPointer = &myVariable; // Declares a const pointer. The pointer cannot be
reassigned to point to something else, but the underlying data member can be changed
• const Type * const myPointer = &myVariable; // Declares a const pointer-to-const.

Remarks
A variable marked as const cannot1 be changed. Attempting to call any non-const operations on it
will result in a compiler error.

1: Well, it can be changed through const_cast, but you should almost never use that

Examples
Const local variables

Declaration and usage.

// a is const int, so it can't be changed


const int a = 15;
a = 12; // Error: can't assign new value to const variable
a += 1; // Error: can't assign new value to const variable

Binding of references and pointers

int &b = a; // Error: can't bind non-const reference to const variable


const int &c = a; // OK; c is a const reference

int *d = &a; // Error: can't bind pointer-to-non-const to const variable


const int *e = &a // OK; e is a pointer-to-const

int f = 0;
e = &f; // OK; e is a non-const pointer-to-const,
// which means that it can be rebound to new int* or const int*

*e = 1 // Error: e is a pointer-to-const which means that


// the value it points to can't be changed through dereferencing e

int *g = &f;
*g = 1; // OK; this value still can be changed through dereferencing
// a pointer-not-to-const

https://riptutorial.com/ 167
Const pointers

int a = 0, b = 2;

const int* pA = &a; // pointer-to-const. `a` can't be changed through this


int* const pB = &a; // const pointer. `a` can be changed, but this pointer can't.
const int* const pC = &a; // const pointer-to-const.

//Error: Cannot assign to a const reference


*pA = b;

pA = &b;

*pB = b;

//Error: Cannot assign to const pointer


pB = &b;

//Error: Cannot assign to a const reference


*pC = b;

//Error: Cannot assign to const pointer


pC = &b;

Const member functions

Member functions of a class can be declared const, which tells the compiler and future readers
that this function will not modify the object:

class MyClass
{
private:
int myInt_;
public:
int myInt() const { return myInt_; }
void setMyInt(int myInt) { myInt_ = myInt; }
};

In a const member function, the this pointer is effectively a const MyClass * instead of a MyClass *.
This means that you cannot change any member variables within the function; the compiler will
emit a warning. So setMyInt could not be declared const.

You should almost always mark member functions as const when possible. Only const member
functions can be called on a const MyClass.

static methods cannot be declared as const. This is because a static method belongs to a class
and is not called on object; therefore it can never modify object's internal variables. So declaring
static methods as const would be redundant.

Avoiding duplication of code in const and non-const getter methods.

In C++ methods that differs only by const qualifier can be overloaded. Sometimes there may be a
need of two versions of getter that return a reference to some member.

https://riptutorial.com/ 168
Let Foo be a class, that has two methods that perform identical operations and returns a reference
to an object of type Bar:

class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}

const Bar& GetBar(/* some arguments */) const


{
/* some calculations */
return bar;
}

// ...
};

The only difference between them is that one method is non-const and return a non-const
reference (that can be use to modify object) and the second is const and returns const reference.

To avoid the code duplication, there is a temptation to call one method from another. However, we
can not call non-const method from the const one. But we can call const method from non-const
one. That will require as to use 'const_cast' to remove the const qualifier.

The solution is:

struct Foo
{
Bar& GetBar(/*arguments*/)
{
return const_cast<Bar&>(const_cast<const Foo*>(this)->GetBar(/*arguments*/));
}

const Bar& GetBar(/*arguments*/) const


{
/* some calculations */
return foo;
}
};

In code above, we call const version of GetBar from the non-const GetBar by casting this to const
type: const_cast<const Foo*>(this). Since we call const method from non-const, the object itself is
non-const, and casting away the const is allowed.

Examine the following more complete example:

#include <iostream>

class Student
{
public:

https://riptutorial.com/ 169
char& GetScore(bool midterm)
{
return const_cast<char&>(const_cast<const Student*>(this)->GetScore(midterm));
}

const char& GetScore(bool midterm) const


{
if (midterm)
{
return midtermScore;
}
else
{
return finalScore;
}
}

private:
char midtermScore;
char finalScore;
};

int main()
{
// non-const object
Student a;
// We can assign to the reference. Non-const version of GetScore is called
a.GetScore(true) = 'B';
a.GetScore(false) = 'A';

// const object
const Student b(a);
// We still can call GetScore method of const object,
// because we have overloaded const version of GetScore
std::cout << b.GetScore(true) << b.GetScore(false) << '\n';
}

Read const keyword online: https://riptutorial.com/cplusplus/topic/2386/const-keyword

https://riptutorial.com/ 170
Chapter 29: Constant class member
functions
Remarks
What does 'const member functions' of a class really means. The simple definition seems to be
that, a const member function cannot change the object. But what does 'can not change' really
means here. It simply means that you cannot do an assignment for class data members.

However, you can do other indirect operations like inserting an entry into a map as shown in the
example. Allowing this might look like this const function is modifying the object (yes, it does in
one sense), but it is allowed.

So, the real meaning is that a const member function cannot do an assignment for the class data
variables. But it can do other stuff like explained in the example.

Examples
constant member function

#include <iostream>
#include <map>
#include <string>

using namespace std;

class A {
public:
map<string, string> * mapOfStrings;
public:
A() {
mapOfStrings = new map<string, string>();
}

void insertEntry(string const & key, string const & value) const {
(*mapOfStrings)[key] = value; // This works? Yes it does.
delete mapOfStrings; // This also works
mapOfStrings = new map<string, string>(); // This * does * not work
}

void refresh() {
delete mapOfStrings;
mapOfStrings = new map<string, string>(); // Works as refresh is non const function
}

void getEntry(string const & key) const {


cout << mapOfStrings->at(key);
}
};

int main(int argc, char* argv[]) {

https://riptutorial.com/ 171
A var;
var.insertEntry("abc", "abcValue");
var.getEntry("abc");
getchar();
return 0;
}

Read Constant class member functions online:


https://riptutorial.com/cplusplus/topic/7120/constant-class-member-functions

https://riptutorial.com/ 172
Chapter 30: constexpr
Introduction
constexpr is a keyword that can be used to mark a variable's value as a constant expression, a
function as potentially usable in constant expressions, or (since C++17) an if statement as having
only one of its branches selected to be compiled.

Remarks
The constexpr keyword was added in C++11 but for a few years since the C++11 standard was
published, not all major compilers supported it. at the time that the C++11 standard was published.
As of the time of publication of C++14, all major compilers support constexpr.

Examples
constexpr variables

A variable declared constexpr is implicitly const and its value may be used as a constant
expression.

Comparison with #define

A constexpr is type-safe replacement for #define based compile-time expressions. With constexpr
the compile-time evaluated expression is replaced with the result. For example:

C++11

int main()
{
constexpr int N = 10 + 2;
cout << N;
}

will produce the following code:

cout << 12;

A pre-processor based compile-time macro would be different. Consider:

#define N 10 + 2

int main()
{
cout << N;
}

https://riptutorial.com/ 173
will produce:

cout << 10 + 2;

which will obviously be converted to cout << 10 + 2;. However, the compiler would have to do
more work. Also, it creates a problem if not used correctly.

For example (with #define):

cout << N * 2;

forms:

cout << 10 + 2 * 2; // 14

But a pre-evaluated constexpr would correctly give 24.

Comparison with const

A const variable is a variable which needs memory for its storage. A constexpr does not. A
constexpr produces compile time constant, which cannot be changed. You may argue that const
may also not be changed. But consider:

int main()
{
const int size1 = 10;
const int size2 = abs(10);

int arr_one[size1];
int arr_two[size2];
}

With most compilers the second statement will fail (may work with GCC, for example). The size of
any array, as you might know, has to be a constant expression (i.e. results in compile-time value).
The second variable size2 is assigned some value that is decided at runtime (even though you
know it is 10, for the compiler it is not compile-time).

This means that a const may or may not be a true compile-time constant. You cannot guarantee or
enforce that a particular const value is absolutely compile-time. You may use #define but it has its
own pitfalls.

Therefore simply use:

C++11

int main()
{
constexpr int size = 10;

int arr[size];
}

https://riptutorial.com/ 174
A constexpr expression must evaluate to a compile-time value. Thus, you cannot use:

C++11

constexpr int size = abs(10);

Unless the function (abs) is itself returning a constexpr.

All basic types can be initialized with constexpr.

C++11

constexpr bool FailFatal = true;


constexpr float PI = 3.14f;
constexpr char* site= "StackOverflow";

Interestingly, and conveniently, you may also use auto:

C++11

constexpr auto domain = ".COM"; // const char * const domain = ".COM"


constexpr auto PI = 3.14; // constexpr double

constexpr functions

A function that is declared constexpr is implicitly inline and calls to such a function potentially yield
constant expressions. For example, the following function, if called with constant expression
arguments, yields a constant expression too:

C++11

constexpr int Sum(int a, int b)


{
return a + b;
}

Thus, the result of the function call may be used as an array bound or a template argument, or to
initialize a constexpr variable:

C++11

int main()
{
constexpr int S = Sum(10,20);

int Array[S];
int Array2[Sum(20,30)]; // 50 array size, compile time
}

Note that if you remove constexpr from function's return type specification, assignment to S will not
work, as S is a constexpr variable, and must be assigned a compile-time const. Similarly, size of

https://riptutorial.com/ 175
array will also not be a constant-expression, if function Sum is not constexpr.

Interesting thing about constexpr functions is that you may also use it like ordinary functions:

C++11

int a = 20;
auto sum = Sum(a, abs(-20));

Sumwill not be a constexpr function now, it will be compiled as an ordinary function, taking variable
(non-constant) arguments, and returning non-constant value. You need not to write two functions.

It also means that if you try to assign such call to a non-const variable, it won't compile:

C++11

int a = 20;
constexpr auto sum = Sum(a, abs(-20));

The reason is simple: constexpr must only be assigned a compile-time constant. However, the
above function call makes Sum a non-constexpr (R-value is non-const, but L-value is declaring itself
to be constexpr).

The constexpr function must also return a compile-time constant. Following will not compile:

C++11

constexpr int Sum(int a, int b)


{
int a1 = a; // ERROR
return a + b;
}

Because a1 is a non-constexpr variable, and prohibits the function from being a true constexpr
function. Making it constexpr and assigning it a will also not work - since value of a (incoming
parameter) is still not yet known:

C++11

constexpr int Sum(int a, int b)


{
constexpr int a1 = a; // ERROR
..

Furthermore, following will also not compile:

C++11

constexpr int Sum(int a, int b)


{
return abs(a) + b; // or abs(a) + abs(b)

https://riptutorial.com/ 176
}

Since abs(a) is not a constant expression (even abs(10) will not work, since abs is not returning a
constexpr int !

What about this?

C++11

constexpr int Abs(int v)


{
return v >= 0 ? v : -v;
}

constexpr int Sum(int a, int b)


{
return Abs(a) + b;
}

We crafted our own Abs function which is a constexpr, and the body of Abs also doesn't break any
rule. Also, at the call site (inside Sum), the expression evaluates to a constexpr. Hence, the call to
Sum(-10, 20) will be a compile-time constant expression resulting to 30.

Static if statement

C++17

The if constexpr statement can be used to conditionally compile code. The condition must be a
constant expression. The branch not selected is discarded. A discarded statement inside a
template is not instantiated. For example:

template<class T, class ... Rest>


void g(T &&p, Rest &&...rs)
{
// ... handle p
if constexpr (sizeof...(rs) > 0)
g(rs...); // never instantiated with an empty argument list
}

In addition, variables and functions that are odr-used only inside discarded statements are not
required to be defined, and discarded return statements are not used for function return type
deduction.

if constexpr is distinct from #ifdef. #ifdef conditionally compiles code, but only based on
conditions that can be evaluated at preprocessing time. For example, #ifdef could not be used to
conditionally compile code depending on the value of a template parameter. On the other hand, if
constexpr cannot be used to discard syntactically invalid code, while #ifdef can.

if constexpr(false) {
foobar; // error; foobar has not been declared
std::vector<int> v("hello, world"); // error; no matching constructor
}

https://riptutorial.com/ 177
Read constexpr online: https://riptutorial.com/cplusplus/topic/3899/constexpr

https://riptutorial.com/ 178
Chapter 31: Copy Elision
Examples
Purpose of copy elision

There are places in the standard where an object is copied or moved in order to initialize an
object. Copy elision (sometimes called return value optimization) is an optimization whereby,
under certain specific circumstances, a compiler is permitted to avoid the copy or move even
though the standard says that it must happen.

Consider the following function:

std::string get_string()
{
return std::string("I am a string.");
}

According to the strict wording of the standard, this function will initialize a temporary std::string,
then copy/move that into the return value object, then destroy the temporary. The standard is very
clear that this is how the code is interpreted.

Copy elision is a rule that permits a C++ compiler to ignore the creation of the temporary and its
subsequent copy/destruction. That is, the compiler can take the initializing expression for the
temporary and initialize the function's return value from it directly. This obviously saves
performance.

However, it does have two visible effects on the user:

1. The type must have the copy/move constructor that would have been called. Even if the
compiler elides the copy/move, the type must still be able to have been copied/moved.

2. Side-effects of copy/move constructors are not guaranteed in circumstances where elision


can happen. Consider the following:

C++11

struct my_type
{
my_type() = default;
my_type(const my_type &) {std::cout <<"Copying\n";}
my_type(my_type &&) {std::cout <<"Moving\n";}
};

my_type func()
{
return my_type();
}

https://riptutorial.com/ 179
What will calling func do? Well, it will never print "Copying", since the temporary is an rvalue and
my_type is a moveable type. So will it print "Moving"?

Without the copy elision rule, this would be required to always print "Moving". But because the
copy elision rule exists, the move constructor may or may not be called; it is implementation-
dependent.

And therefore, you cannot depend on the calling of copy/move constructors in contexts where
elision is possible.

Because elision is an optimization, your compiler may not support elision in all cases. And
regardless of whether the compiler elides a particular case or not, the type must still support the
operation being elided. So if a copy construction is elided, the type must still have a copy
constructor, even though it will not be called.

Guaranteed copy elision

C++17

Normally, elision is an optimization. While virtually every compiler support copy elision in the
simplest of cases, having elision still places a particular burden on users. Namely, the type who's
copy/move is being elided must still have the copy/move operation that was elided.

For example:

std::mutex a_mutex;
std::lock_guard<std::mutex> get_lock()
{
return std::lock_guard<std::mutex>(a_mutex);
}

This might be useful in cases where a_mutex is a mutex that is privately held by some system, yet
an external user might want to have a scoped lock to it.

This is also not legal, because std::lock_guard cannot be copied or moved. Even though virtually
every C++ compiler will elide the copy/move, the standard still requires the type to have that
operation available.

Until C++17.

C++17 mandates elision by effectively redefining the very meaning of certain expressions so that
no copy/moving takes place. Consider the above code.

Under pre-C++17 wording, that code says to create a temporary and then use the temporary to
copy/move into the return value, but the temporary copy can be elided. Under C++17 wording, that
does not create a temporary at all.

In C++17, any prvalue expression, when used to initialize an object of the same type as the
expression, does not generate a temporary. The expression directly initializes that object. If you
return a prvalue of the same type as the return value, then the type need not have a copy/move

https://riptutorial.com/ 180
constructor. And therefore, under C++17 rules, the above code can work.

The C++17 wording works in cases where the prvalue's type matches the type being initialized. So
given get_lock above, this will also not require a copy/move:

std::lock_guard the_lock = get_lock();

Since the result of get_lock is a prvalue expression being used to initialize an object of the same
type, no copying or moving will happen. That expression never creates a temporary; it is used to
directly initialize the_lock. There is no elision because there is no copy/move to be elided elide.

The term "guaranteed copy elision" is therefore something of a misnomer, but that is the name of
the feature as it is proposed for C++17 standardization. It does not guarantee elision at all; it
eliminates the copy/move altogether, redefining C++ so that there never was a copy/move to be
elided.

This feature only works in cases involving a prvalue expression. As such, this uses the usual
elision rules:

std::mutex a_mutex;
std::lock_guard<std::mutex> get_lock()
{
std::lock_guard<std::mutex> my_lock(a_mutex);
//Do stuff
return my_lock;
}

While this is a valid case for copy elision, C++17 rules do not eliminate the copy/move in this case.
As such, the type must still have a copy/move constructor to use to initialize the return value. And
since lock_guard does not, this is still a compile error. Implementations are allowed to refuse to
elide copies when passing or returning an object of trivially-copyable type. This is to allow moving
such objects around in registers, which some ABIs might mandate in their calling conventions.

struct trivially_copyable {
int a;
};

void foo (trivially_copyable a) {}

foo(trivially_copyable{}); //copy elision not mandated

Return value elision

If you return a prvalue expression from a function, and the prvalue expression has the same type
as the function's return type, then the copy from the prvalue temporary can be elided:

std::string func()
{
return std::string("foo");
}

https://riptutorial.com/ 181
Pretty much all compilers will elide the temporary construction in this case.

Parameter elision

When you pass an argument to a function, and the argument is a prvalue expression of the
function's parameter type, and this type is not a reference, then the prvalue's construction can be
elided.

void func(std::string str) { ... }

func(std::string("foo"));

This says to create a temporary string, then move it into the function parameter str. Copy elision
permits this expression to directly create the object in str, rather than using a temporary+move.

This is a useful optimization for cases where a constructor is declared explicit. For example, we
could have written the above as func("foo"), but only because string has an implicit constructor
that converts from a const char* to a string. If that constructor was explicit, we would be forced to
use a temporary to call the explicit constructor. Copy elision saves us from having to do a
needless copy/move.

Named return value elision

If you return an lvalue expression from a function, and this lvalue:

• represents an automatic variable local to that function, which will be destroyed after the
return
• the automatic variable is not a function parameter
• and the type of the variable is the same type as the function's return type

If all of these are the case, then the copy/move from the lvalue can be elided:

std::string func()
{
std::string str("foo");
//Do stuff
return str;
}

More complex cases are eligible for elision, but the more complex the case, the less likely the
compiler will be to actually elide it:

std::string func()
{
std::string ret("foo");
if(some_condition)
{
return "bar";
}
return ret;
}

https://riptutorial.com/ 182
The compiler could still elide ret, but the chances of them doing so go down.

As noted earlier, elision is not permitted for value parameters.

std::string func(std::string str)


{
str.assign("foo");
//Do stuff
return str; //No elision possible
}

Copy initialization elision

If you use a prvalue expression to copy initialize a variable, and that variable has the same type as
the prvalue expression, then the copying can be elided.

std::string str = std::string("foo");

Copy initialization effectively transforms this into std::string str("foo"); (there are minor
differences).

This also works with return values:

std::string func()
{
return std::string("foo");
}

std::string str = func();

Without copy elision, this would provoke 2 calls to std::string's move constructor. Copy elision
permits this to call the move constructor 1 or zero times, and most compilers will opt for the latter.

Read Copy Elision online: https://riptutorial.com/cplusplus/topic/2489/copy-elision

https://riptutorial.com/ 183
Chapter 32: Copying vs Assignment
Syntax
• Copy Constructor
• MyClass( const MyClass& other );
• MyClass( MyClass& other );
• MyClass( volatile const MyClass& other );
• MyClass( volatile MyClass& other );
• Assignment Constructor
• MyClass& operator=( const MyClass& rhs );
• MyClass& operator=( MyClass& rhs );
• MyClass& operator=( MyClass rhs );
• const MyClass& operator=( const MyClass& rhs );
• const MyClass& operator=( MyClass& rhs );
• const MyClass& operator=( MyClass rhs );
• MyClass operator=( const MyClass& rhs );
• MyClass operator=( MyClass& rhs );
• MyClass operator=( MyClass rhs );

Parameters

Right Hand Side of the equality for both copy and assignment
rhs constructors. For example the assignment constructor : MyClass
operator=( MyClass& rhs );

Placeholder Placeholder

Remarks
Other Good Resources for further research :

What's the difference between assignment operator and copy constructor?

assignment operator vs. copy constructor C++

GeeksForGeeks

C++ Articles

Examples
Assignment Operator

https://riptutorial.com/ 184
The Assignment Operator is when you replace the data with an already existing(previously
initialized) object with some other object's data. Lets take this as an example:

// Assignment Operator
#include <iostream>
#include <string>

using std::cout;
using std::endl;

class Foo
{
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo& operator=(const Foo& rhs)
{
data = rhs.data;
return *this;
}

int data;
};

int main()
{
Foo foo(2); //Foo(int data) called
Foo foo2(42);
foo = foo2; // Assignment Operator Called
cout << foo.data << endl; //Prints 42
}

You can see here I call the assignment operator when I already initialized the foo object. Then
later I assign foo2 to foo . All the changes to appear when you call that equal sign operator is
defined in your operator= function. You can see a runnable output here: http://cpp.sh/3qtbm

Copy Constructor

Copy constructor on the other hand , is the complete opposite of the Assignment Constructor. This
time, it is used to initialize an already nonexistent(or non-previously initialized) object. This means
it copies all the data from the object you are assigning it to , without actually initializing the object
that is being copied onto. Now Let's take a look at the same code as before but modify the
assignment constructor to be a copy constructor :

// Copy Constructor
#include <iostream>
#include <string>

using std::cout;
using std::endl;

class Foo
{

https://riptutorial.com/ 185
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo(const Foo& rhs)
{
data = rhs.data;
}

int data;
};

int main()
{
Foo foo(2); //Foo(int data) called
Foo foo2 = foo; // Copy Constructor called
cout << foo2.data << endl;
}

You can see here Foo foo2 = foo; in the main function I immediately assign the object before
actually initializing it, which as said before means it's a copy constructor. And notice that I didn't
need to pass the parameter int for the foo2 object since I automatically pulled the previous data
from the object foo. Here is an example output : http://cpp.sh/5iu7

Copy Constructor Vs Assignment Constructor

Ok we have briefly looked over what the copy constructor and assignment constructor are above
and gave examples of each now let's see both of them in the same code. This code will be similar
as above two. Let's take this :

// Copy vs Assignment Constructor


#include <iostream>
#include <string>

using std::cout;
using std::endl;

class Foo
{
public:
Foo(int data)
{
this->data = data;
}
~Foo(){};
Foo(const Foo& rhs)
{
data = rhs.data;
}

Foo& operator=(const Foo& rhs)


{
data = rhs.data;
return *this;
}

https://riptutorial.com/ 186
int data;
};

int main()
{
Foo foo(2); //Foo(int data) / Normal Constructor called
Foo foo2 = foo; //Copy Constructor Called
cout << foo2.data << endl;

Foo foo3(42);
foo3=foo; //Assignment Constructor Called
cout << foo3.data << endl;
}

Output:

2
2

Here you can see we first call the copy constructor by executing the line Foo foo2 = foo; . Since
we didn't initialize it previously. And then next we call the assignment operator on foo3 since it was
already initialized foo3=foo;

Read Copying vs Assignment online: https://riptutorial.com/cplusplus/topic/7158/copying-vs-


assignment

https://riptutorial.com/ 187
Chapter 33: Curiously Recurring Template
Pattern (CRTP)
Introduction
A pattern in which a class inherits from a class template with itself as one of its template
parameters. CRTP is usually used to provide static polymorphism in C++.

Examples
The Curiously Recurring Template Pattern (CRTP)

CRTP is a powerful, static alternative to virtual functions and traditional inheritance that can be
used to give types properties at compile time. It works by having a base class template which
takes, as one of its template parameters, the derived class. This permits it to legally perform a
static_cast of its this pointer to the derived class.

Of course, this also means that a CRTP class must always be used as the base class of some
other class. And the derived class must pass itself to the base class.

C++14

Let's say you have a set of containers that all support the functions begin() and end(). The
standard library's requirements for containers require more functionality. We can design a CRTP
base class that provides that functionality, based solely on begin() and end():

#include <iterator>
template <typename Sub>
class Container {
private:
// self() yields a reference to the derived type
Sub& self() { return *static_cast<Sub*>(this); }
Sub const& self() const { return *static_cast<Sub const*>(this); }

public:
decltype(auto) front() {
return *self().begin();
}

decltype(auto) back() {
return *std::prev(self().end());
}

decltype(auto) size() const {


return std::distance(self().begin(), self().end());
}

decltype(auto) operator[](std::size_t i) {
return *std::next(self().begin(), i);

https://riptutorial.com/ 188
}
};

The above class provides the functions front(), back(), size(), and operator[] for any subclass
which provides begin() and end(). An example subclass is a simple dynamically allocated array:

#include <memory>
// A dynamically allocated array
template <typename T>
class DynArray : public Container<DynArray<T>> {
public:
using Base = Container<DynArray<T>>;

DynArray(std::size_t size)
: size_{size},
data_{std::make_unique<T[]>(size_)}
{ }

T* begin() { return data_.get(); }


const T* begin() const { return data_.get(); }
T* end() { return data_.get() + size_; }
const T* end() const { return data_.get() + size_; }

private:
std::size_t size_;
std::unique_ptr<T[]> data_;
};

Users of the DynArray class can use the interfaces provided by the CRTP base class easily as
follows:

DynArray<int> arr(10);
arr.front() = 2;
arr[2] = 5;
assert(arr.size() == 10);

Usefulness: This pattern particularly avoids virtual function calls at run-time which occur to
traverse down the inheritance hierarchy and simply relies on static casts:

DynArray<int> arr(10);
DynArray<int>::Base & base = arr;
base.begin(); // no virtual calls

The only static cast inside the function begin() in the base class Container<DynArray<int>> allows
the compiler to drastically optimize the code and no virtual table look up happens at runtime.

Limitations: Because the base class is templated and different for two different DynArrays it is not
possible to store pointers to their base classes in an type-homogenous array as one could
generally do with normal inheritance where the base class is not dependent on the derived type:

class A {};
class B: public A{};

A* a = new B;

https://riptutorial.com/ 189
CRTP to avoid code duplication

The example in Visitor Pattern provides a compelling use-case for CRTP:

struct IShape
{
virtual ~IShape() = default;

virtual void accept(IShapeVisitor&) const = 0;


};

struct Circle : IShape


{
// ...
// Each shape has to implement this method the same way
void accept(IShapeVisitor& visitor) const override { visitor.visit(*this); }
// ...
};

struct Square : IShape


{
// ...
// Each shape has to implement this method the same way
void accept(IShapeVisitor& visitor) const override { visitor.visit(*this); }
// ...
};

Each child type of IShape needs to implement the same function the same way. That's a lot of extra
typing. Instead, we can introduce a new type in the hierarchy that does this for us:

template <class Derived>


struct IShapeAcceptor : IShape {
void accept(IShapeVisitor& visitor) const override {
// visit with our exact type
visitor.visit(*static_cast<Derived const*>(this));
}
};

And now, each shape simply needs to inherit from the acceptor:

struct Circle : IShapeAcceptor<Circle>


{
Circle(const Point& center, double radius) : center(center), radius(radius) {}
Point center;
double radius;
};

struct Square : IShapeAcceptor<Square>


{
Square(const Point& topLeft, double sideLength) : topLeft(topLeft), sideLength(sideLength)
{}
Point topLeft;
double sideLength;
};

No duplicate code necessary.

https://riptutorial.com/ 190
Read Curiously Recurring Template Pattern (CRTP) online:
https://riptutorial.com/cplusplus/topic/9269/curiously-recurring-template-pattern--crtp-

https://riptutorial.com/ 191
Chapter 34: Data Structures in C++
Examples
Linked List implementation in C++

Creating a List Node

class listNode
{
public:
int data;
listNode *next;
listNode(int val):data(val),next(NULL){}
};

Creating List class

class List
{
public:
listNode *head;
List():head(NULL){}
void insertAtBegin(int val);
void insertAtEnd(int val);
void insertAtPos(int val);
void remove(int val);
void print();
~List();
};

Insert a new node at the beginning of the list

void List::insertAtBegin(int val)//inserting at front of list


{
listNode *newnode = new listNode(val);
newnode->next=this->head;
this->head=newnode;
}

Insert a new node at the end of the list

void List::insertAtEnd(int val) //inserting at end of list


{
if(head==NULL)
{
insertAtBegin(val);
return;
}
listNode *newnode = new listNode(val);
listNode *ptr=this->head;
while(ptr->next!=NULL)

https://riptutorial.com/ 192
{
ptr=ptr->next;
}
ptr->next=newnode;
}

Insert at a particular position in list

void List::insertAtPos(int pos,int val)


{
listNode *newnode=new listNode(val);
if(pos==1)
{
//as head
newnode->next=this->head;
this->head=newnode;
return;
}
pos--;
listNode *ptr=this->head;
while(ptr!=NULL && --pos)
{
ptr=ptr->next;
}
if(ptr==NULL)
return;//not enough elements
newnode->next=ptr->next;
ptr->next=newnode;
}

Removing a node from the list

void List::remove(int toBeRemoved)//removing an element


{
if(this->head==NULL)
return; //empty
if(this->head->data==toBeRemoved)
{
//first node to be removed
listNode *temp=this->head;
this->head=this->head->next;
delete(temp);
return;
}
listNode *ptr=this->head;
while(ptr->next!=NULL && ptr->next->data!=toBeRemoved)
ptr=ptr->next;
if(ptr->next==NULL)
return;//not found
listNode *temp=ptr->next;
ptr->next=ptr->next->next;
delete(temp);
}

Print the list

void List::print()//printing the list

https://riptutorial.com/ 193
{
listNode *ptr=this->head;
while(ptr!=NULL)
{
cout<<ptr->data<<" " ;
ptr=ptr->next;
}
cout<<endl;
}

Destructor for the list

List::~List()
{
listNode *ptr=this->head,*next=NULL;
while(ptr!=NULL)
{
next=ptr->next;
delete(ptr);
ptr=next;
}
}

Read Data Structures in C++ online: https://riptutorial.com/cplusplus/topic/7485/data-structures-in-


cplusplus

https://riptutorial.com/ 194
Chapter 35: Date and time using header
Examples
Measuring time using

The system_clock can be used to measure the time elapsed during some part of a program's
execution.

c++11

#include <iostream>
#include <chrono>
#include <thread>

int main() {
auto start = std::chrono::system_clock::now(); // This and "end"'s type is
std::chrono::time_point
{ // The code to test
std::this_thread::sleep_for(std::chrono::seconds(2));
}
auto end = std::chrono::system_clock::now();

std::chrono::duration<double> elapsed = end - start;


std::cout << "Elapsed time: " << elapsed.count() << "s";
}

In this example, sleep_for was used to make the active thread sleep for a time period measured in
std::chrono::seconds, but the code between braces could be any function call that takes some time
to execute.

Find number of days between two dates

This example shows how to find number of days between two dates. A date is specified by
year/month/day of month, and additionally hour/minute/second.

Program calculates number of days in years since 2000.

#include <iostream>
#include <string>
#include <chrono>
#include <ctime>

/***
* Creates a std::tm structure from raw date.
*
* \param year (must be 1900 or greater)
* \param month months since January – [1, 12]
* \param day day of the month – [1, 31]
* \param minutes minutes after the hour – [0, 59]
* \param seconds seconds after the minute – [0, 61](until C++11) / [0, 60] (since C++11)
*

https://riptutorial.com/ 195
* Based on http://en.cppreference.com/w/cpp/chrono/c/tm
*/
std::tm CreateTmStruct(int year, int month, int day, int hour, int minutes, int seconds) {
struct tm tm_ret = {0};

tm_ret.tm_sec = seconds;
tm_ret.tm_min = minutes;
tm_ret.tm_hour = hour;
tm_ret.tm_mday = day;
tm_ret.tm_mon = month - 1;
tm_ret.tm_year = year - 1900;

return tm_ret;
}

int get_days_in_year(int year) {

using namespace std;


using namespace std::chrono;

// We want results to be in days


typedef duration<int, ratio_multiply<hours::period, ratio<24> >::type> days;

// Create start time span


std::tm tm_start = CreateTmStruct(year, 1, 1, 0, 0, 0);
auto tms = system_clock::from_time_t(std::mktime(&tm_start));

// Create end time span


std::tm tm_end = CreateTmStruct(year + 1, 1, 1, 0, 0, 0);
auto tme = system_clock::from_time_t(std::mktime(&tm_end));

// Calculate time duration between those two dates


auto diff_in_days = std::chrono::duration_cast<days>(tme - tms);

return diff_in_days.count();
}

int main()
{
for ( int year = 2000; year <= 2016; ++year )
std::cout << "There are " << get_days_in_year(year) << " days in " << year << "\n";
}

Read Date and time using header online: https://riptutorial.com/cplusplus/topic/3936/date-and-


time-using--chrono--header

https://riptutorial.com/ 196
Chapter 36: decltype
Introduction
The keyword decltype can be used to get the type of a variable, function or an expression.

Examples
Basic Example

This example just illustrates how this keyword can be used.

int a = 10;

// Assume that type of variable 'a' is not known here, or it may


// be changed by programmer (from int to long long, for example).
// Hence we declare another variable, 'b' of the same type using
// decltype keyword.
decltype(a) b; // 'decltype(a)' evaluates to 'int'

If, for example, someone changes, type of 'a' to:

float a=99.0f;

Then the type of variable b now automatically becomes float.

Another example

Let's say we have vector:

std::vector<int> intVector;

And we want to declare an iterator for this vector. An obvious idea is to use auto. However, it may
be needed just declare an iterator variable (and not to assign it to anything). We would do:

vector<int>::iterator iter;

However, with decltype it becomes easy and less error prone (if type of intVector changes).

decltype(intVector)::iterator iter;

Alternatively:

decltype(intVector.begin()) iter;

In second example, the return type of begin is used to determine the actual type, which is

https://riptutorial.com/ 197
vector<int>::iterator.

If we need a const_iterator, we just need to use cbegin:

decltype(intVector.cbegin()) iter; // vector<int>::const_iterator

Read decltype online: https://riptutorial.com/cplusplus/topic/9930/decltype

https://riptutorial.com/ 198
Chapter 37: Design pattern implementation in
C++
Introduction
On this page, you can find examples of how design patterns are implemented in C++. For the
details on these patterns, you can check out the design patterns documentation.

Remarks
A design pattern is a general reusable solution to a commonly occurring problem within a given
context in software design.

Examples
Observer pattern

Observer Pattern's intent is to define a one-to-many dependency between objects so that when
one object changes state, all its dependents are notified and updated automatically.

The subject and observers define the one-to-many relationship. The observers are dependent on
the subject such that when the subject's state changes, the observers get notified. Depending on
the notification, the observers may also be updated with new values.

Here is the example from the book "Design Patterns" by Gamma.

#include <iostream>
#include <vector>

class Subject;

class Observer
{
public:
virtual ~Observer() = default;
virtual void Update(Subject&) = 0;
};

class Subject
{
public:
virtual ~Subject() = default;
void Attach(Observer& o) { observers.push_back(&o); }
void Detach(Observer& o)
{
observers.erase(std::remove(observers.begin(), observers.end(), &o));
}
void Notify()
{

https://riptutorial.com/ 199
for (auto* o : observers) {
o->Update(*this);
}
}
private:
std::vector<Observer*> observers;
};

class ClockTimer : public Subject


{
public:

void SetTime(int hour, int minute, int second)


{
this->hour = hour;
this->minute = minute;
this->second = second;

Notify();
}

int GetHour() const { return hour; }


int GetMinute() const { return minute; }
int GetSecond() const { return second; }

private:
int hour;
int minute;
int second;
};

class DigitalClock: public Observer


{
public:
explicit DigitalClock(ClockTimer& s) : subject(s) { subject.Attach(*this); }
~DigitalClock() { subject.Detach(*this); }
void Update(Subject& theChangedSubject) override
{
if (&theChangedSubject == &subject) {
Draw();
}
}

void Draw()
{
int hour = subject.GetHour();
int minute = subject.GetMinute();
int second = subject.GetSecond();

std::cout << "Digital time is " << hour << ":"


<< minute << ":"
<< second << std::endl;
}

private:
ClockTimer& subject;
};

class AnalogClock: public Observer


{
public:

https://riptutorial.com/ 200
explicit AnalogClock(ClockTimer& s) : subject(s) { subject.Attach(*this); }
~AnalogClock() { subject.Detach(*this); }
void Update(Subject& theChangedSubject) override
{
if (&theChangedSubject == &subject) {
Draw();
}
}
void Draw()
{
int hour = subject.GetHour();
int minute = subject.GetMinute();
int second = subject.GetSecond();

std::cout << "Analog time is " << hour << ":"


<< minute << ":"
<< second << std::endl;
}
private:
ClockTimer& subject;
};

int main()
{
ClockTimer timer;

DigitalClock digitalClock(timer);
AnalogClock analogClock(timer);

timer.SetTime(14, 41, 36);


}

Output:

Digital time is 14:41:36


Analog time is 14:41:36

Here are the summary of the pattern:

1. Objects (DigitalClock or AnalogClock object) use the Subject interfaces (Attach() or Detach())
either to subscribe (register) as observers or unsubscribe (remove) themselves from being
observers (subject.Attach(*this); , subject.Detach(*this);.

2. Each subject can have many observers( vector<Observer*> observers;).

3. All observers need to implement the Observer interface. This interface just has one method,
Update(), that gets called when the Subject's state changes (Update(Subject &))

4. In addition to the Attach() and Detach() methods, the concrete subject implements a Notify()
method that is used to update all the current observers whenever state changes. But in this
case, all of them are done in the parent class, Subject (Subject::Attach (Observer&), void
Subject::Detach(Observer&) and void Subject::Notify() .

5. The Concrete object may also have methods for setting and getting its state.

https://riptutorial.com/ 201
6. Concrete observers can be any class that implements the Observer interface. Each observer
subscribe (register) with a concrete subject to receive update (subject.Attach(*this); ).

7. The two objects of Observer Pattern are loosely coupled, they can interact but with little
knowledge of each other.

Variation:

Signal and Slots

Signals and slots is a language construct introduced in Qt, which makes it easy to implement the
Observer pattern while avoiding boilerplate code. The concept is that controls (also known as
widgets) can send signals containing event information which can be received by other controls
using special functions known as slots. The slot in Qt must be a class member declared as such.
The signal/slot system fits well with the way Graphical User Interfaces are designed. Similarly, the
signal/slot system can be used for asynchronous I/O (including sockets, pipes, serial devices, etc.)
event notification or to associate timeout events with appropriate object instances and methods or
functions. No registration/deregistration/invocation code need be written, because Qt's Meta
Object Compiler (MOC) automatically generates the needed infrastructure.

The C# language also supports a similar construct although with a different terminology and
syntax: events play the role of signals, and delegates are the slots. Additionally, a delegate can be
a local variable, much like a function pointer, while a slot in Qt must be a class member declared
as such.

Adapter Pattern

Convert the interface of a class into another interface clients expect. Adapter (or Wrapper) lets
classes work together that couldn't otherwise because of incompatible interfaces. Adapter
pattern's motivation is that we can reuse existing software if we can modify the interface.

1. Adapter pattern relies on object composition.

2. Client calls operation on Adapter object.

3. Adapter calls Adaptee to carry out the operation.

4. In STL, stack adapted from vector: When stack executes push(), underlying vector does
vector::push_back().

Example:

#include <iostream>

// Desired interface (Target)


class Rectangle
{
public:
virtual void draw() = 0;
};

https://riptutorial.com/ 202
// Legacy component (Adaptee)
class LegacyRectangle
{
public:
LegacyRectangle(int x1, int y1, int x2, int y2) {
x1_ = x1;
y1_ = y1;
x2_ = x2;
y2_ = y2;
std::cout << "LegacyRectangle(x1,y1,x2,y2)\n";
}
void oldDraw() {
std::cout << "LegacyRectangle: oldDraw(). \n";
}
private:
int x1_;
int y1_;
int x2_;
int y2_;
};

// Adapter wrapper
class RectangleAdapter: public Rectangle, private LegacyRectangle
{
public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
}

void draw() {
std::cout << "RectangleAdapter: draw().\n";
oldDraw();
}
};

int main()
{
int x = 20, y = 50, w = 300, h = 200;
Rectangle *r = new RectangleAdapter(x,y,w,h);
r->draw();
}

//Output:
//LegacyRectangle(x1,y1,x2,y2)
//RectangleAdapter(x,y,x+w,x+h)

Summary of the code:

1. The client thinks he is talking to a Rectangle

2. The target is the Rectangle class. This is what the client invokes method on.

Rectangle *r = new RectangleAdapter(x,y,w,h);


r->draw();

3. Note that the adapter class uses multiple inheritance.

https://riptutorial.com/ 203
class RectangleAdapter: public Rectangle, private LegacyRectangle {
...
}

4. The Adapter RectangleAdapter lets the LegacyRectangle responds to request (draw() on a


Rectangle) by inheriting BOTH classes.

5. The LegacyRectangle class does not have the same methods (draw()) as Rectangle, but the
Adapter(RectangleAdapter) can take the Rectangle method calls and turn around and invoke
method on the LegacyRectangle, oldDraw().

class RectangleAdapter: public Rectangle, private LegacyRectangle {


public:
RectangleAdapter(int x, int y, int w, int h):
LegacyRectangle(x, y, x + w, y + h) {
std::cout << "RectangleAdapter(x,y,x+w,x+h)\n";
}

void draw() {
std::cout << "RectangleAdapter: draw().\n";
oldDraw();
}
};

Adapter design pattern translates the interface for one class into a compatible but different
interface. So, this is similar to the proxy pattern in that it's a single-component wrapper. But the
interface for the adapter class and the original class may be different.

As we've seen in the example above, this adapter pattern is useful to expose a different interface
for an existing API to allow it to work with other code. Also, by using adapter pattern, we can take
heterogeneous interfaces, and transform them to provide consistent API.

Bridge pattern has a structure similar to an object adapter, but Bridge has a different intent: It is
meant to separate an interface from its implementation so that they can be varied easily and
independently. An adapter is meant to change the interface of an existing object.

Factory Pattern

Factory pattern decouples object creation and allows creation by name using a common interface:

class Animal{
public:
virtual std::shared_ptr<Animal> clone() const = 0;
virtual std::string getname() const = 0;
};

class Bear: public Animal{


public:
virtual std::shared_ptr<Animal> clone() const override
{
return std::make_shared<Bear>(*this);
}
virtual std::string getname() const override

https://riptutorial.com/ 204
{
return "bear";
}
};

class Cat: public Animal{


public:
virtual std::shared_ptr<Animal> clone() const override
{
return std::make_shared<Cat>(*this);
}
virtual std::string getname() const override
{
return "cat";
}
};

class AnimalFactory{
public:
static std::shared_ptr<Animal> getAnimal( const std::string& name )
{
if ( name == "bear" )
return std::make_shared<Bear>();
if ( name == "cat" )
return std::shared_ptr<Cat>();

return nullptr;
}

};

Builder Pattern with Fluent API

The Builder Pattern decouples the creation of the object from the object itself. The main idea
behind is that an object does not have to be responsible for its own creation. The correct and
valid assembly of a complex object may be a complicated task in itself, so this task can be
delegated to another class.

Inspired by the Email Builder in C#, I've decided to make a C++ version here. An Email object is
not necessarily a very complex object, but it can demonstrate the pattern.

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

// Forward declaring the builder


class EmailBuilder;

class Email
{
public:
friend class EmailBuilder; // the builder can access Email's privates

https://riptutorial.com/ 205
static EmailBuilder make();

string to_string() const {


stringstream stream;
stream << "from: " << m_from
<< "\nto: " << m_to
<< "\nsubject: " << m_subject
<< "\nbody: " << m_body;
return stream.str();
}

private:
Email() = default; // restrict construction to builder

string m_from;
string m_to;
string m_subject;
string m_body;
};

class EmailBuilder
{
public:
EmailBuilder& from(const string &from) {
m_email.m_from = from;
return *this;
}

EmailBuilder& to(const string &to) {


m_email.m_to = to;
return *this;
}

EmailBuilder& subject(const string &subject) {


m_email.m_subject = subject;
return *this;
}

EmailBuilder& body(const string &body) {


m_email.m_body = body;
return *this;
}

operator Email&&() {
return std::move(m_email); // notice the move
}

private:
Email m_email;
};

EmailBuilder Email::make()
{
return EmailBuilder();
}

// Bonus example!
std::ostream& operator <<(std::ostream& stream, const Email& email)
{
stream << email.to_string();
return stream;

https://riptutorial.com/ 206
}

int main()
{
Email mail = Email::make().from("[email protected]")
.to("[email protected]")
.subject("C++ builders")
.body("I like this API, don't you?");

cout << mail << endl;


}

For older versions of C++, one may just ignore the std::move operation and remove the && from
the conversion operator (although this will create a temporary copy).

The builder finishes its work when it releases the built email by the operator Email&&(). In this
example, the builder is a temporary object and returns the email before being destroyed. You
could also use an explicit operation like Email EmailBuilder::build() {...} instead of the
conversion operator.

Pass the builder around


A great feature the Builder Pattern provides is the ability to use several actors to build an object
together. This is done by passing the builder to the other actors that will each one give some
more information to the built object. This is specially powerful when you are building some sort of
query, adding filters and other specifications.

void add_addresses(EmailBuilder& builder)


{
builder.from("[email protected]")
.to("[email protected]");
}

void compose_mail(EmailBuilder& builder)


{
builder.subject("I know the subject")
.body("And the body. Someone else knows the addresses.");
}

int main()
{
EmailBuilder builder;
add_addresses(builder);
compose_mail(builder);

Email mail = builder;


cout << mail << endl;
}

Design variant : Mutable object

https://riptutorial.com/ 207
You can change the design of this pattern to fit your needs. I'll give one variant.

In the given example the Email object is immutable, i.e., it's properties can't be modified because
there is no access to them. This was a desired feature. If you need to modify the object after its
creation you have to provide some setters to it. Since those setters would be duplicated in the
builder, you may consider to do it all in one class (no builder class needed anymore).
Nevertheless, I would consider the need to make the built object mutable in the first place.

Read Design pattern implementation in C++ online:


https://riptutorial.com/cplusplus/topic/4335/design-pattern-implementation-in-cplusplus

https://riptutorial.com/ 208
Chapter 38: Digit separators
Examples
Digit Separator

Numeric literals of more than a few digits are hard to read.

• Pronounce 7237498123.
• Compare 237498123 with 237499123 for equality.
• Decide whether 237499123 or 20249472 is larger.

C++14 define Simple Quotation Mark ' as a digit separator, in numbers and user-defined literals.
This can make it easier for human readers to parse large numbers.

C++14

long long decn = 1'000'000'000ll;


long long hexn = 0xFFFF'FFFFll;
long long octn = 00'23'00ll;
long long binn = 0b1010'0011ll;

Single quotes mark are ignored when determining its value.

Example:

• The literals 1048576, 1'048'576, 0X100000, 0x10'0000, and 0'004'000'000 all have the same
value.
• The literals 1.602'176'565e-19 and 1.602176565e-19 have the same value.

The position of the single quotes is irrelevant. All the following are equivalent:

C++14

long long a1 = 123456789ll;


long long a2 = 123'456'789ll;
long long a3 = 12'34'56'78'9ll;
long long a4 = 12345'6789ll;

It is also allowed in user-defined literals:

C++14

std::chrono::seconds tiempo = 1'674'456s + 5'300h;

Read Digit separators online: https://riptutorial.com/cplusplus/topic/10595/digit-separators

https://riptutorial.com/ 209
Chapter 39: Enumeration
Examples
Basic Enumeration Declaration

Standard enumerations allow users to declare a useful name for a set of integers. The names are
collectively referred to as enumerators. An enumeration and its associated enumerators are
defined as follows:

enum myEnum
{
enumName1,
enumName2,
};

An enumeration is a type, one which is distinct from all other types. In this case, the name of this
type is myEnum. Objects of this type are expected to assume the value of an enumerator within the
enumeration.

The enumerators declared within the enumeration are constant values of the type of the
enumeration. Though the enumerators are declared within the type, the scope operator :: is not
needed to access the name. So the name of the first enumerator is enumName1.

C++11

The scope operator can be optionally used to access an enumerator within an enumeration. So
enumName1 can also be spelled myEnum::enumName1.

Enumerators are assigned integer values starting from 0 and increasing by 1 for each enumerator
in an enumeration. So in the above case, enumName1 has the value 0, while enumName2 has the value
1.

Enumerators can also be assigned a specific value by the user; this value must be an integral
constant expression. Enumerators who's values are not explicitly provided will have their value set
to the value of the previous enumerator + 1.

enum myEnum
{
enumName1 = 1, // value will be 1
enumName2 = 2, // value will be 2
enumName3, // value will be 3, previous value + 1
enumName4 = 7, // value will be 7
enumName5, // value will be 8
enumName6 = 5, // value will be 5, legal to go backwards
enumName7 = 3, // value will be 3, legal to reuse numbers
enumName8 = enumName4 + 2, // value will be 9, legal to take prior enums and adjust them
};

https://riptutorial.com/ 210
Enumeration in switch statements

A common use for enumerators is for switch statements and so they commonly appear in state
machines. In fact a useful feature of switch statements with enumerations is that if no default
statement is included for the switch, and not all values of the enum have been utilized, the
compiler will issue a warning.

enum State {
start,
middle,
end
};

...

switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]

Iteration over an enum

There is no built-in to iterate over enumeration.

But there are several ways

• for enum with only consecutive values:

enum E {
Begin,
E1 = Begin,
E2,
// ..
En,
End
};

for (E e = E::Begin; e != E::End; ++e) {


// Do job with e
}

C++11

with enum class, operator ++ has to be implemented:

E& operator ++ (E& e)


{
if (e == E::End) {
throw std::out_of_range("for E& operator ++ (E&)");
}
e = E(static_cast<std::underlying_type<E>::type>(e) + 1);
return e;

https://riptutorial.com/ 211
}

• using a container as std::vector

enum E {
E1 = 4,
E2 = 8,
// ..
En
};

std::vector<E> build_all_E()
{
const E all[] = {E1, E2, /*..*/ En};

return std::vector<E>(all, all + sizeof(all) / sizeof(E));


}

std::vector<E> all_E = build_all_E();

and then

for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) {


E e = *it;
// Do job with e;
}

C++11

• or std::initializer_list and a simpler syntax:

enum E {
E1 = 4,
E2 = 8,
// ..
En
};

constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};

and then

for (auto e : all_E) {


// Do job with e
}

Scoped enums

C++11 introduces what are known as scoped enums. These are enumerations whose members
must be qualified with enumname::membername. Scoped enums are declared using the enum class
syntax. For example, to store the colors in a rainbow:

enum class rainbow {

https://riptutorial.com/ 212
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};

To access a specific color:

rainbow r = rainbow::INDIGO;

enum classes cannot be implicitly converted to ints without a cast. So int x = rainbow::RED is
invalid.

Scoped enums also allow you to specify the underlying type, which is the type used to represent a
member. By default it is int. In a Tic-Tac-Toe game, you may store the piece as

enum class piece : char {


EMPTY = '\0',
X = 'X',
O = 'O',
};

As you may notice, enums can have a trailing comma after the last member.

Enum forward declaration in C++11

Scoped enumerations:

...
enum class Status; // Forward declaration
Status doWork(); // Use the forward declaration
...
enum class Status { Invalid, Success, Fail };
Status doWork() // Full declaration required for implementation
{
return Status::Success;
}

Unscoped enumerations:

...
enum Status: int; // Forward declaration, explicit type required
Status doWork(); // Use the forward declaration
...
enum Status: int{ Invalid=0, Success, Fail }; // Must match forward declare type
static_assert( Success == 1 );

An in-depth multi-file example can be found here: Blind fruit merchant example

Read Enumeration online: https://riptutorial.com/cplusplus/topic/2796/enumeration

https://riptutorial.com/ 213
Chapter 40: Exceptions
Examples
Catching exceptions

A try/catch block is used to catch exceptions. The code in the try section is the code that may
throw an exception, and the code in the catch clause(s) handles the exception.

#include <iostream>
#include <string>
#include <stdexcept>

int main() {
std::string str("foo");

try {
str.at(10); // access element, may throw std::out_of_range
} catch (const std::out_of_range& e) {
// what() is inherited from std::exception and contains an explanatory message
std::cout << e.what();
}
}

Multiple catch clauses may be used to handle multiple exception types. If multiple catch clauses
are present, the exception handling mechanism tries to match them in order of their appearance
in the code:

std::string str("foo");

try {
str.reserve(2); // reserve extra capacity, may throw std::length_error
str.at(10); // access element, may throw std::out_of_range
} catch (const std::length_error& e) {
std::cout << e.what();
} catch (const std::out_of_range& e) {
std::cout << e.what();
}

Exception classes which are derived from a common base class can be caught with a single catch
clause for the common base class. The above example can replace the two catch clauses for
std::length_error and std::out_of_range with a single clause for std:exception:

std::string str("foo");

try {
str.reserve(2); // reserve extra capacity, may throw std::length_error
str.at(10); // access element, may throw std::out_of_range
} catch (const std::exception& e) {
std::cout << e.what();
}

https://riptutorial.com/ 214
Because the catch clauses are tried in order, be sure to write more specific catch clauses first,
otherwise your exception handling code might never get called:

try {
/* Code throwing exceptions omitted. */
} catch (const std::exception& e) {
/* Handle all exceptions of type std::exception. */
} catch (const std::runtime_error& e) {
/* This block of code will never execute, because std::runtime_error inherits
from std::exception, and all exceptions of type std::exception were already
caught by the previous catch clause. */
}

Another possibility is the catch-all handler, which will catch any thrown object:

try {
throw 10;
} catch (...) {
std::cout << "caught an exception";
}

Rethrow (propagate) exception

Sometimes you want to do something with the exception you catch (like write to log or print a
warning) and let it bubble up to the upper scope to be handled. To do so, you can rethrow any
exception you catch:

try {
... // some code here
} catch (const SomeException& e) {
std::cout << "caught an exception";
throw;
}

Using throw; without arguments will re-throw the currently caught exception.

C++11

To rethrow a managed std::exception_ptr, the C++ Standard Library has the rethrow_exception
function that can be used by including the <exception> header in your program.

#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>

void handle_eptr(std::exception_ptr eptr) // passing by value is ok


{
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch(const std::exception& e) {
std::cout << "Caught exception \"" << e.what() << "\"\n";

https://riptutorial.com/ 215
}
}

int main()
{
std::exception_ptr eptr;
try {
std::string().at(1); // this generates an std::out_of_range
} catch(...) {
eptr = std::current_exception(); // capture
}
handle_eptr(eptr);
} // destructor for std::out_of_range called here, when the eptr is destructed

Function Try Blocks In constructor

The only way to catch exception in initializer list:

struct A : public B
{
A() try : B(), foo(1), bar(2)
{
// constructor body
}
catch (...)
{
// exceptions from the initializer list and constructor are caught here
// if no exception is thrown here
// then the caught exception is re-thrown.
}

private:
Foo foo;
Bar bar;
};

Function Try Block for regular function

void function_with_try_block()
try
{
// try block body
}
catch (...)
{
// catch block body
}

Which is equivalent to

void function_with_try_block()
{
try
{
// try block body
}

https://riptutorial.com/ 216
catch (...)
{
// catch block body
}
}

Note that for constructors and destructors, the behavior is different as the catch block re-throws an
exception anyway (the caught one if there is no other throw in the catch block body).

The function main is allowed to have a function try block like any other function, but main's function
try block will not catch exceptions that occur during the construction of a non-local static variable
or the destruction of any static variable. Instead, std::terminate is called.

Function Try Blocks In destructor

struct A
{
~A() noexcept(false) try
{
// destructor body
}
catch (...)
{
// exceptions of destructor body are caught here
// if no exception is thrown here
// then the caught exception is re-thrown.
}
};

Note that, although this is possible, one needs to be very careful with throwing from destructor, as
if a destructor called during stack unwinding throws an exception, std::terminate is called.

Best practice: throw by value, catch by const reference

In general, it is considered good practice to throw by value (rather than by pointer), but catch by
(const) reference.

try {
// throw new std::runtime_error("Error!"); // Don't do this!
// This creates an exception object
// on the heap and would require you to catch the
// pointer and manage the memory yourself. This can
// cause memory leaks!

throw std::runtime_error("Error!");
} catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl;
}

One reason why catching by reference is a good practice is that it eliminates the need to
reconstruct the object when being passed to the catch block (or when propagating through to other
catch blocks). Catching by reference also allows the exceptions to be handled polymorphically and
avoids object slicing. However, if you are rethrowing an exception (like throw e;, see example

https://riptutorial.com/ 217
below), you can still get object slicing because the throw e; statement makes a copy of the
exception as whatever type is declared:

#include <iostream>

struct BaseException {
virtual const char* what() const { return "BaseException"; }
};

struct DerivedException : BaseException {


// "virtual" keyword is optional here
virtual const char* what() const { return "DerivedException"; }
};

int main(int argc, char** argv) {


try {
try {
throw DerivedException();
} catch (const BaseException& e) {
std::cout << "First catch block: " << e.what() << std::endl;
// Output ==> First catch block: DerivedException

throw e; // This changes the exception to BaseException


// instead of the original DerivedException!
}
} catch (const BaseException& e) {
std::cout << "Second catch block: " << e.what() << std::endl;
// Output ==> Second catch block: BaseException
}
return 0;
}

If you are sure that you are not going to do anything to change the exception (like add information
or modify the message), catching by const reference allows the compiler to make optimizations
and can improve performance. But this can still cause object splicing (as seen in the example
above).

Warning: Beware of throwing unintended exceptions in catch blocks, especially related to


allocating extra memory or resources. For example, constructing logic_error, runtime_error or their
subclasses might throw bad_alloc due to memory running out when copying the exception string,
I/O streams might throw during logging with respective exception masks set, etc.

Nested exception

C++11

During exception handling there is a common use case when you catch a generic exception from
a low-level function (such as a filesystem error or data transfer error) and throw a more specific
high-level exception which indicates that some high-level operation could not be performed (such
as being unable to publish a photo on Web). This allows exception handling to react to specific
problems with high level operations and also allows, having only error an message, the
programmer to find a place in the application where an exception occurred. Downside of this
solution is that exception callstack is truncated and original exception is lost. This forces
developers to manually include text of original exception into a newly created one.

https://riptutorial.com/ 218
Nested exceptions aim to solve the problem by attaching low-level exception, which describes the
cause, to a high level exception, which describes what it means in this particular case.

std::nested_exception allows to nest exceptions thanks to std::throw_with_nested:

#include <stdexcept>
#include <exception>
#include <string>
#include <fstream>
#include <iostream>

struct MyException
{
MyException(const std::string& message) : message(message) {}
std::string message;
};

void print_current_exception(int level)


{
try {
throw;
} catch (const std::exception& e) {
std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
} catch (const MyException& e) {
std::cerr << std::string(level, ' ') << "MyException: " << e.message << '\n';
} catch (...) {
std::cerr << "Unkown exception\n";
}
}

void print_current_exception_with_nested(int level = 0)


{
try {
throw;
} catch (...) {
print_current_exception(level);
}
try {
throw;
} catch (const std::nested_exception& nested) {
try {
nested.rethrow_nested();
} catch (...) {
print_current_exception_with_nested(level + 1); // recursion
}
} catch (...) {
//Empty // End recursion
}
}

// sample function that catches an exception and wraps it in a nested exception


void open_file(const std::string& s)
{
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch(...) {
std::throw_with_nested(MyException{"Couldn't open " + s});
}
}

https://riptutorial.com/ 219
// sample function that catches an exception and wraps it in a nested exception
void run()
{
try {
open_file("nonexistent.file");
} catch(...) {
std::throw_with_nested( std::runtime_error("run() failed") );
}
}

// runs the sample function above and prints the caught exception
int main()
{
try {
run();
} catch(...) {
print_current_exception_with_nested();
}
}

Possible output:

exception: run() failed


MyException: Couldn't open nonexistent.file
exception: basic_ios::clear

If you work only with exceptions inherited from std::exception, code can even be simplified.

std::uncaught_exceptions

c++17

C++17 introduces int (to replace the limited bool


std::uncaught_exceptions()
std::uncaught_exception()) to know how many exceptions are currently uncaught. That allows for a
class to determine if it is destroyed during a stack unwinding or not.

#include <exception>
#include <string>
#include <iostream>

// Apply change on destruction:


// Rollback in case of exception (failure)
// Else Commit (success)
class Transaction
{
public:
Transaction(const std::string& s) : message(s) {}
Transaction(const Transaction&) = delete;
Transaction& operator =(const Transaction&) = delete;
void Commit() { std::cout << message << ": Commit\n"; }
void RollBack() noexcept(true) { std::cout << message << ": Rollback\n"; }

// ...

~Transaction() {

https://riptutorial.com/ 220
if (uncaughtExceptionCount == std::uncaught_exceptions()) {
Commit(); // May throw.
} else { // current stack unwinding
RollBack();
}
}

private:
std::string message;
int uncaughtExceptionCount = std::uncaught_exceptions();
};

class Foo
{
public:
~Foo() {
try {
Transaction transaction("In ~Foo"); // Commit,
// even if there is an uncaught exception
//...
} catch (const std::exception& e) {
std::cerr << "exception/~Foo:" << e.what() << std::endl;
}
}
};

int main()
{
try {
Transaction transaction("In main"); // RollBack
Foo foo; // ~Foo commit its transaction.
//...
throw std::runtime_error("Error");
} catch (const std::exception& e) {
std::cerr << "exception/main:" << e.what() << std::endl;
}
}

Output:

In ~Foo: Commit
In main: Rollback
exception/main:Error

Custom exception

You shouldn't throw raw values as exceptions, instead use one of the standard exception classes
or make your own.

Having your own exception class inherited from std::exception is a good way to go about it. Here's
a custom exception class which directly inherits from std::exception:

#include <exception>

class Except: virtual public std::exception {

protected:

https://riptutorial.com/ 221
int error_number; ///< Error number
int error_offset; ///< Error offset
std::string error_message; ///< Error message

public:

/** Constructor (C++ STL string, int, int).


* @param msg The error message
* @param err_num Error number
* @param err_off Error offset
*/
explicit
Except(const std::string& msg, int err_num, int err_off):
error_number(err_num),
error_offset(err_off),
error_message(msg)
{}

/** Destructor.
* Virtual to allow for subclassing.
*/
virtual ~Except() throw () {}

/** Returns a pointer to the (constant) error description.


* @return A pointer to a const char*. The underlying memory
* is in possession of the Except object. Callers must
* not attempt to free the memory.
*/
virtual const char* what() const throw () {
return error_message.c_str();
}

/** Returns error number.


* @return #error_number
*/
virtual int getErrorNumber() const throw() {
return error_number;
}

/**Returns error offset.


* @return #error_offset
*/
virtual int getErrorOffset() const throw() {
return error_offset;
}

};

An example throw catch:

try {
throw(Except("Couldn't do what you were expecting", -12, -34));
} catch (const Except& e) {
std::cout<<e.what()
<<"\nError number: "<<e.getErrorNumber()
<<"\nError offset: "<<e.getErrorOffset();
}

https://riptutorial.com/ 222
As you are not only just throwing a dumb error message, also some other values representing
what the error exactly was, your error handling becomes much more efficient and meaningful.

There's an exception class that let's you handle error messages nicely :std::runtime_error

You can inherit from this class too:

#include <stdexcept>

class Except: virtual public std::runtime_error {

protected:

int error_number; ///< Error number


int error_offset; ///< Error offset

public:

/** Constructor (C++ STL string, int, int).


* @param msg The error message
* @param err_num Error number
* @param err_off Error offset
*/
explicit
Except(const std::string& msg, int err_num, int err_off):
std::runtime_error(msg)
{
error_number = err_num;
error_offset = err_off;

/** Destructor.
* Virtual to allow for subclassing.
*/
virtual ~Except() throw () {}

/** Returns error number.


* @return #error_number
*/
virtual int getErrorNumber() const throw() {
return error_number;
}

/**Returns error offset.


* @return #error_offset
*/
virtual int getErrorOffset() const throw() {
return error_offset;
}

};

Note that I haven't overridden the what() function from the base class (std::runtime_error) i.e we
will be using the base class's version of what(). You can override it if you have further agenda.

Read Exceptions online: https://riptutorial.com/cplusplus/topic/1354/exceptions

https://riptutorial.com/ 223
Chapter 41: Explicit type conversions
Introduction
An expression can be explicitly converted or cast to type T using dynamic_cast<T>, static_cast<T>,
reinterpret_cast<T>, or const_cast<T>, depending on what type of cast is intended.

C++ also supports function-style cast notation, T(expr), and C-style cast notation, (T)expr.

Syntax
• simple-type-specifier ( )
• simple-type-specifier ( expression-list )
• simple-type-specifier braced-init-list
• typename-specifier ( )
• typename-specifier ( expression-list )
• typename-specifier braced-init-list
• dynamic_cast < type-id > ( expression )
• static_cast < type-id > ( expression )
• reinterpret_cast < type-id > ( expression )
• const_cast < type-id > ( expression )
• ( type-id ) cast-expression

Remarks
All six cast notations have one thing in common:

• Casting to an lvalue reference type, as in dynamic_cast<Derived&>(base), yields an lvalue.


Therefore, when you want to do something with the same object but treat it as a different
type, you would cast to an lvalue reference type.
• Casting to an rvalue reference type, as in static_cast<string&&>(s), yields an rvalue.
• Casting to a non-reference type, as in (int)x, yields a prvalue, which may be thought of as a
copy of the value being cast, but with a different type from the original.

The reinterpret_cast keyword is responsible for performing two different kinds of "unsafe"
conversions:

• The "type punning" conversions, which can be used to access memory of one type as
though it is of a different type.
• Conversions between integer types and pointer types, in either direction.

The static_cast keyword can perform a variety of different conversions:

• Base to derived conversions

https://riptutorial.com/ 224
• Any conversion that can be done by a direct initialization, including both implicit conversions
and conversions that call an explicit constructor or conversion function. See here and here
for more details.

• To void, which discards the value of the expression.

// on some compilers, suppresses warning about x being unused


static_cast<void>(x);

• Between arithmetic and enumeration types, and between different enumeration types. See
enum conversions

• From pointer to member of derived class, to pointer to member of base class. The types
pointed to must match. See derived to base conversion for pointers to members

• void* to T*.

C++11

• From an lvalue to an xvalue, as in std::move. See move semantics.

Examples
Base to derived conversion

A pointer to base class can be converted to a pointer to derived class using static_cast.
static_cast does not do any run-time checking and can lead to undefined behaviour when the
pointer does not actually point to the desired type.

struct Base {};


struct Derived : Base {};
Derived d;
Base* p1 = &d;
Derived* p2 = p1; // error; cast required
Derived* p3 = static_cast<Derived*>(p1); // OK; p2 now points to Derived object
Base b;
Base* p4 = &b;
Derived* p5 = static_cast<Derived*>(p4); // undefined behaviour since p4 does not
// point to a Derived object

Likewise, a reference to base class can be converted to a reference to derived class using
static_cast.

struct Base {};


struct Derived : Base {};
Derived d;
Base& r1 = d;
Derived& r2 = r1; // error; cast required
Derived& r3 = static_cast<Derived&>(r1); // OK; r3 now refers to Derived object

If the source type is polymorphic, dynamic_cast can be used to perform a base to derived

https://riptutorial.com/ 225
conversion. It performs a run-time check and failure is recoverable instead of producing undefined
behaviour. In the pointer case, a null pointer is returned upon failure. In the reference case, an
exception is thrown upon failure of type std::bad_cast (or a class derived from std::bad_cast).

struct Base { virtual ~Base(); }; // Base is polymorphic


struct Derived : Base {};
Base* b1 = new Derived;
Derived* d1 = dynamic_cast<Derived*>(b1); // OK; d1 points to Derived object
Base* b2 = new Base;
Derived* d2 = dynamic_cast<Derived*>(b2); // d2 is a null pointer

Casting away constness

A pointer to a const object can be converted to a pointer to non-const object using the const_cast
keyword. Here we use const_cast to call a function that is not const-correct. It only accepts a non-
const char* argument even though it never writes through the pointer:

void bad_strlen(char*);
const char* s = "hello, world!";
bad_strlen(s); // compile error
bad_strlen(const_cast<char*>(s)); // OK, but it's better to make bad_strlen accept const char*

const_cast to reference type can be used to convert a const-qualified lvalue into a non-const-
qualified value.

const_cast is dangerous because it makes it impossible for the C++ type system to prevent you
from trying to modify a const object. Doing so results in undefined behavior.

const int x = 123;


int& mutable_x = const_cast<int&>(x);
mutable_x = 456; // may compile, but produces *undefined behavior*

Type punning conversion

A pointer (resp. reference) to an object type can be converted to a pointer (resp. reference) to any
other object type using reinterpret_cast. This does not call any constructors or conversion
functions.

int x = 42;
char* p = static_cast<char*>(&x); // error: static_cast cannot perform this conversion
char* p = reinterpret_cast<char*>(&x); // OK
*p = 'z'; // maybe this modifies x (see below)

C++11

The result of reinterpret_cast represents the same address as the operand, provided that the
address is appropriately aligned for the destination type. Otherwise, the result is unspecified.

int x = 42;
char& r = reinterpret_cast<char&>(x);

https://riptutorial.com/ 226
const void* px = &x;
const void* pr = &r;
assert(px == pr); // should never fire

C++11

The result of reinterpret_cast is unspecified, except that a pointer (resp. reference) will survive a
round trip from the source type to the destination type and back, as long as the destination type's
alignment requirement is not stricter than that of the source type.

int x = 123;
unsigned int& r1 = reinterpret_cast<unsigned int&>(x);
int& r2 = reinterpret_cast<int&>(r1);
r2 = 456; // sets x to 456

On most implementations, reinterpret_cast does not change the address, but this requirement
was not standardized until C++11.

reinterpret_castcan also be used to convert from one pointer-to-data-member type to another, or


one pointer-to-member-function type to another.

Use of reinterpret_cast is considered dangerous because reading or writing through a pointer or


reference obtained using reinterpret_cast may trigger undefined behaviour when the source and
destination types are unrelated.

Conversion between pointer and integer

An object pointer (including void*) or function pointer can be converted to an integer type using
reinterpret_cast. This will only compile if the destination type is long enough. The result is
implementation-defined and typically yields the numeric address of the byte in memory that the
pointer pointers to.

Typically, long or unsigned long is long enough to hold any pointer value, but this is not guaranteed
by the standard.

C++11

If the types std::intptr_t and std::uintptr_t exist, they are guaranteed to be long enough to hold
a void* (and hence any pointer to object type). However, they are not guaranteed to be long
enough to hold a function pointer.

Similarly, reinterpret_cast can be used to convert an integer type into a pointer type. Again the
result is implementation-defined, but a pointer value is guaranteed to be unchanged by a round
trip through an integer type. The standard does not guarantee that the value zero is converted to a
null pointer.

void register_callback(void (*fp)(void*), void* arg); // probably a C API


void my_callback(void* x) {
std::cout << "the value is: " << reinterpret_cast<long>(x); // will probably compile
}

https://riptutorial.com/ 227
long x;
std::cin >> x;
register_callback(my_callback,
reinterpret_cast<void*>(x)); // hopefully this doesn't lose information...

Conversion by explicit constructor or explicit conversion function

A conversion that involves calling an explicit constructor or conversion function can't be done
implicitly. We can request that the conversion be done explicitly using static_cast. The meaning is
the same as that of a direct initialization, except that the result is a temporary.

class C {
std::unique_ptr<int> p;
public:
explicit C(int* p) : p(p) {}
};
void f(C c);
void g(int* p) {
f(p); // error: C::C(int*) is explicit
f(static_cast<C>(p)); // ok
f(C(p)); // equivalent to previous line
C c(p); f(c); // error: C is not copyable
}

Implicit conversion

static_cast can perform any implicit conversion. This use of static_cast can occasionally be
useful, such as in the following examples:

• When passing arguments to an ellipsis, the "expected" argument type is not statically known,
so no implicit conversion will occur.

const double x = 3.14;


printf("%d\n", static_cast<int>(x)); // prints 3
// printf("%d\n", x); // undefined behaviour; printf is expecting an int here
// alternative:
// const int y = x; printf("%d\n", y);

Without the explicit type conversion, a double object would be passed to the ellipsis, and
undefined behaviour would occur.

• A derived class assignment operator can call a base class assignment operator like so:

struct Base { /* ... */ };


struct Derived : Base {
Derived& operator=(const Derived& other) {
static_cast<Base&>(*this) = other;
// alternative:
// Base& this_base_ref = *this; this_base_ref = other;
}
};

https://riptutorial.com/ 228
Enum conversions

static_castcan convert from an integer or floating point type to an enumeration type (whether
scoped or unscoped), and vice versa. It can also convert between enumeration types.

• The conversion from an unscoped enumeration type to an arithmetic type is an implicit


conversion; it is possible, but not necessary, to use static_cast.

C++11

• When a scoped enumeration type is converted to an arithmetic type:

○ If the enum's value can be represented exactly in the destination type, the result is that
value.
○ Otherwise, if the destination type is an integer type, the result is unspecified.
○ Otherwise, if the destination type is a floating point type, the result is the same as that
of converting to the underlying type and then to the floating point type.

Example:

enum class Format {


TEXT = 0,
PDF = 1000,
OTHER = 2000,
};
Format f = Format::PDF;
int a = f; // error
int b = static_cast<int>(f); // ok; b is 1000
char c = static_cast<char>(f); // unspecified, if 1000 doesn't fit into char
double d = static_cast<double>(f); // d is 1000.0... probably

• When an integer or enumeration type is converted to an enumeration type:

○ If the original value is within the destination enum's range, the result is that value. Note
that this value might be unequal to all enumerators.
○ Otherwise, the result is unspecified (<= C++14) or undefined (>= C++17).

Example:

enum Scale {
SINGLE = 1,
DOUBLE = 2,
QUAD = 4
};
Scale s1 = 1; // error
Scale s2 = static_cast<Scale>(2); // s2 is DOUBLE
Scale s3 = static_cast<Scale>(3); // s3 has value 3, and is not equal to any enumerator
Scale s9 = static_cast<Scale>(9); // unspecified value in C++14; UB in C++17

C++11

• When a floating point type is converted to an enumeration type, the result is the same as

https://riptutorial.com/ 229
converting to the enum's underlying type and then to the enum type.

enum Direction {
UP = 0,
LEFT = 1,
DOWN = 2,
RIGHT = 3,
};
Direction d = static_cast<Direction>(3.14); // d is RIGHT

Derived to base conversion for pointers to members

A pointer to member of derived class can be converted to a pointer to member of base class using
static_cast. The types pointed to must match.

If the operand is a null pointer to member value, the result is also a null pointer to member value.

Otherwise, the conversion is only valid if the member pointed to by the operand actually exists in
the destination class, or if the destination class is a base or derived class of the class containing
the member pointed to by the operand. static_cast does not check for validity. If the conversion is
not valid, the behaviour is undefined.

struct A {};
struct B { int x; };
struct C : A, B { int y; double z; };
int B::*p1 = &B::x;
int C::*p2 = p1; // ok; implicit conversion
int B::*p3 = p2; // error
int B::*p4 = static_cast<int B::*>(p2); // ok; p4 is equal to p1
int A::*p5 = static_cast<int A::*>(p2); // undefined; p2 points to x, which is a member
// of the unrelated class B
double C::*p6 = &C::z;
double A::*p7 = static_cast<double A::*>(p6); // ok, even though A doesn't contain z
int A::*p8 = static_cast<int A::*>(p6); // error: types don't match

void* to T*

In C++, void* cannot be implicitly converted to T* where T is an object type. Instead, static_cast
should be used to perform the conversion explicitly. If the operand actually points to a T object, the
result points to that object. Otherwise, the result is unspecified.

C++11

Even if the operand does not point to a T object, as long as the operand points to a byte whose
address is properly aligned for the type T, the result of the conversion points to the same byte.

// allocating an array of 100 ints, the hard way


int* a = malloc(100*sizeof(*a)); // error; malloc returns void*
int* a = static_cast<int*>(malloc(100*sizeof(*a))); // ok
// int* a = new int[100]; // no cast needed
// std::vector<int> a(100); // better

const char c = '!';

https://riptutorial.com/ 230
const void* p1 = &c;
const char* p2 = p1; // error
const char* p3 = static_cast<const char*>(p1); // ok; p3 points to c
const int* p4 = static_cast<const int*>(p1); // unspecified in C++03;
// possibly unspecified in C++11 if
// alignof(int) > alignof(char)
char* p5 = static_cast<char*>(p1); // error: casting away constness

C-style casting

C-Style casting can be considered 'Best effort' casting and is named so as it is the only cast which
could be used in C. The syntax for this cast is (NewType)variable.

Whenever this cast is used, it uses one of the following c++ casts (in order):

• const_cast<NewType>(variable)
• static_cast<NewType>(variable)
• const_cast<NewType>(static_cast<const NewType>(variable))
• reinterpret_cast<const NewType>(variable)
• const_cast<NewType>(reinterpret_cast<const NewType>(variable))

Functional casting is very similar, though as a few restrictions as the result of its syntax:
NewType(expression). As a result, only types without spaces can be cast to.

It's better to use new c++ cast, because s more readable and can be spotted easily anywhere
inside a C++ source code and errors will be detected in compile-time, instead in run-time.

As this cast can result in unintended reinterpret_cast, it is often considered dangerous.

Read Explicit type conversions online: https://riptutorial.com/cplusplus/topic/3090/explicit-type-


conversions

https://riptutorial.com/ 231
Chapter 42: Expression templates
Examples
Basic expression templates on element-wise algebraic expressions

Introduction and motivation

Expression templates (denoted as ETs in the following) are a powerful template meta-
programming technique, used to speed-up calculations of sometimes quite expensive
expressions. It is widely used in different domains, for example in implementation of linear algebra
libraries.

For this example, consider the context of linear algebraic computations. More specifically,
computations involving only element-wise operations. This kind of computations are the most
basic applications of ETs, and they serve as a good introduction to how ETs work internally.

Let's look at a motivating example. Consider the computation of the expression:

Vector vec_1, vec_2, vec_3;

// Initializing vec_1, vec_2 and vec_3.

Vector result = vec_1 + vec_2*vec_3;

Here for the sake of simplicity, I'll assume that the class Vector and operation + (vector plus:
element-wise plus operation) and operation * (here means vector inner product: also element-wise
operation) are both correctly implemented, as how they should be, mathematically.

In a conventional implementation without using ETs (or other similar techniques), at least five
constructions of Vector instances take place in order to obtain the final result:

1. Three instances corresponding to vec_1, vec_2 and vec_3.


2. A temporary Vector instance _tmp, representing the result of _tmp = vec_2*vec_3;.
3. Finally with proper use of return value optimization, the construction of final result in
result = vec_1 + _tmp;.

Implementation using ETs can eliminate the creation of temporary Vector _tmp in 2, thus leaving
only four constructions of Vector instances. More interestingly, consider the following expression
which is more complex:

Vector result = vec_1 + (vec_2*vec3 + vec_1)*(vec_2 + vec_3*vec_1);

There will also be four constructions of Vector instances in total: vec_1, vec_2, vec_3 and result. In
other words, in this example, where only element-wise operations are involved, it is

https://riptutorial.com/ 232
guaranteed that no temporary objects will be created from intermediate calculations.

How do ETs work

Basically speaking, ETs for any algebraic computations consist of two building blocks:

1. Pure algebraic expressions (PAE): they are proxies / abstractions of algebraic


expressions. A pure algebraic does not do actual computations, they are merely abstractions
/ modeling of the computation work-flow. A PAE can be a model of either the input or the
output of any algebraic expressions. Instances of PAEs are often considered cheap to
copy.
2. Lazy evaluations: which are implementation of real computations. In the following example,
we will see that for expressions involving only element-wise operations, lazy evaluations can
implement actual computations inside the indexed-access operation on the final result, thus
creating a scheme of evaluation on-demand: a computation is not performed only if the final
result is accessed / asked for.

So, specifically how do we implement ETs in this example? Let's walk through it now.

Consider always the following code snippet:

Vector vec_1, vec_2, vec_3;

// Initializing vec_1, vec_2 and vec_3.

Vector result = vec_1 + vec_2*vec_3;

The expression to compute result can be decomposed further into two sub-expressions:

1. A vector plus expression (denoted as plus_expr)


2. A vector inner product expression (denoted as innerprod_expr).

What ETs do is the following:

• Instead of compute right away each sub-expression, ETs first model the whole expression
using a graphical structure. Each node in the graph represents a PAE. The edge connection
of the nodes represent the actual computation flow. So for the above expression, we obtain
the following graph:

result = plus_expr( vec_1, innerprod_expr(vec_2, vec_3) )


/ \
/ \
/ \
/ innerprod_expr( vec_2, vec_3 )
/ / \
/ / \
/ / \
vec_1 vec_2 vec_3

• The final computation is implemented by looking through the graph hierarchy: since here

https://riptutorial.com/ 233
we are dealing with only element-wise operations, the computation of each indexed value
in result can be done independently: the final evaluation of result can be lazily postponed
to a element-wise evaluation of each element of result. In other words, since the
computation of an element of result, elem_res, can be expressed using corresponding
elements in vec_1 (elem_1), vec_2 (elem_2) and vec_3 (elem_3) as:

elem_res = elem_1 + elem_2*elem_3;

there is therefore no need to create a temporary Vector to store the result of intermediate inner
product: the whole computation for one element can be done altogether, and be encoded
inside the indexed-access operation.

Here are the example codes in action.

File vec.hh : wrapper for std::vector, used to show log when


a construction is called.

#ifndef EXPR_VEC
# define EXPR_VEC

# include <vector>
# include <cassert>
# include <utility>
# include <iostream>
# include <algorithm>
# include <functional>

///
/// This is a wrapper for std::vector. It's only purpose is to print out a log when a
/// vector constructions in called.
/// It wraps the indexed access operator [] and the size() method, which are
/// important for later ETs implementation.
///

// std::vector wrapper.
template<typename ScalarType> class Vector
{
public:
explicit Vector() { std::cout << "ctor called.\n"; };
explicit Vector(int size): _vec(size) { std::cout << "ctor called.\n"; };
explicit Vector(const std::vector<ScalarType> &vec): _vec(vec)
{ std::cout << "ctor called.\n"; };

Vector(const Vector<ScalarType> & vec): _vec{vec()}


{ std::cout << "copy ctor called.\n"; };
Vector(Vector<ScalarType> && vec): _vec(std::move(vec()))
{ std::cout << "move ctor called.\n"; };

Vector<ScalarType> & operator=(const Vector<ScalarType> &) = default;


Vector<ScalarType> & operator=(Vector<ScalarType> &&) = default;

https://riptutorial.com/ 234
decltype(auto) operator[](int indx) { return _vec[indx]; }
decltype(auto) operator[](int indx) const { return _vec[indx]; }

decltype(auto) operator()() & { return (_vec); };


decltype(auto) operator()() const & { return (_vec); };
Vector<ScalarType> && operator()() && { return std::move(*this); }

int size() const { return _vec.size(); }

private:
std::vector<ScalarType> _vec;
};

///
/// These are conventional overloads of operator + (the vector plus operation)
/// and operator * (the vector inner product operation) without using the expression
/// templates. They are later used for bench-marking purpose.
///

// + (vector plus) operator.


template<typename ScalarType>
auto operator+(const Vector<ScalarType> &lhs, const Vector<ScalarType> &rhs)
{
assert(lhs().size() == rhs().size() &&
"error: ops plus -> lhs and rhs size mismatch.");

std::vector<ScalarType> _vec;
_vec.resize(lhs().size());
std::transform(std::cbegin(lhs()), std::cend(lhs()),
std::cbegin(rhs()), std::begin(_vec),
std::plus<>());
return Vector<ScalarType>(std::move(_vec));
}

// * (vector inner product) operator.


template<typename ScalarType>
auto operator*(const Vector<ScalarType> &lhs, const Vector<ScalarType> &rhs)
{
assert(lhs().size() == rhs().size() &&
"error: ops multiplies -> lhs and rhs size mismatch.");

std::vector<ScalarType> _vec;
_vec.resize(lhs().size());
std::transform(std::cbegin(lhs()), std::cend(lhs()),
std::cbegin(rhs()), std::begin(_vec),
std::multiplies<>());
return Vector<ScalarType>(std::move(_vec));
}

#endif //!EXPR_VEC

File expr.hh : implementation of expression templates for


element-wise operations (vector plus and vector inner
product)

https://riptutorial.com/ 235
Let's break it down to sections.

1. Section 1 implements a base class for all expressions. It employs the Curiously Recurring
Template Pattern (CRTP).
2. Section 2 implements the first PAE: a terminal, which is just a wrapper (const reference) of
an input data structure containing real input value for computation.
3. Section 3 implements the second PAE: binary_operation, which is a class template later
used for vector_plus and vector_innerprod. It's parametrized by the type of operation, the
left-hand-side PAE and the right-hand-side PAE. The actual computation is encoded in
the indexed-access operator.
4. Section 4 defines vector_plus and vector_innerprod operations as element-wise operation.
It also overload operator + and * for PAEs: such that these two operations also return PAE.

#ifndef EXPR_EXPR
# define EXPR_EXPR

/// Fwd declaration.


template<typename> class Vector;

namespace expr
{

/// -----------------------------------------
///
/// Section 1.
///
/// The first section is a base class template for all kinds of expression. It
/// employs the Curiously Recurring Template Pattern, which enables its instantiation
/// to any kind of expression structure inheriting from it.
///
/// -----------------------------------------

/// Base class for all expressions.


template<typename Expr> class expr_base
{
public:
const Expr& self() const { return static_cast<const Expr&>(*this); }
Expr& self() { return static_cast<Expr&>(*this); }

protected:
explicit expr_base() {};
int size() const { return self().size_impl(); }
auto operator[](int indx) const { return self().at_impl(indx); }
auto operator()() const { return self()(); };
};

/// -----------------------------------------
///
/// The following section 2 & 3 are abstractions of pure algebraic expressions (PAE).
/// Any PAE can be converted to a real object instance using operator(): it is in
/// this conversion process, where the real computations are done.

///

https://riptutorial.com/ 236
/// Section 2. Terminal
///
/// A terminal is an abstraction wrapping a const reference to the Vector data
/// structure. It inherits from expr_base, therefore providing a unified interface
/// wrapping a Vector into a PAE.
///
/// It provides the size() method, indexed access through at_impl() and a conversion
/// to referenced object through () operator.
///
/// It might no be necessary for user defined data structures to have a terminal
/// wrapper, since user defined structure can inherit expr_base, therefore eliminates
/// the need to provide such terminal wrapper.
///
/// -----------------------------------------

/// Generic wrapper for underlying data structure.


template<typename DataType> class terminal: expr_base<terminal<DataType>>
{
public:
using base_type = expr_base<terminal<DataType>>;
using base_type::size;
using base_type::operator[];
friend base_type;

explicit terminal(const DataType &val): _val(val) {}


int size_impl() const { return _val.size(); };
auto at_impl(int indx) const { return _val[indx]; };
decltype(auto) operator()() const { return (_val); }

private:
const DataType &_val;
};

/// -----------------------------------------
///
/// Section 3. Binary operation expression.
///
/// This is a PAE abstraction of any binary expression. Similarly it inherits from
/// expr_base.
///
/// It provides the size() method, indexed access through at_impl() and a conversion
/// to referenced object through () operator. Each call to the at_impl() method is
/// a element wise computation.
///
/// -----------------------------------------

/// Generic wrapper for binary operations (that are element-wise).


template<typename Ops, typename lExpr, typename rExpr>
class binary_ops: public expr_base<binary_ops<Ops,lExpr,rExpr>>
{
public:
using base_type = expr_base<binary_ops<Ops,lExpr,rExpr>>;
using base_type::size;
using base_type::operator[];
friend base_type;

explicit binary_ops(const Ops &ops, const lExpr &lxpr, const rExpr &rxpr)
: _ops(ops), _lxpr(lxpr), _rxpr(rxpr) {};

https://riptutorial.com/ 237
int size_impl() const { return _lxpr.size(); };

/// This does the element-wise computation for index indx.


auto at_impl(int indx) const { return _ops(_lxpr[indx], _rxpr[indx]); };

/// Conversion from arbitrary expr to concrete data type. It evaluates


/// element-wise computations for all indices.
template<typename DataType> operator DataType()
{
DataType _vec(size());
for(int _ind = 0; _ind < _vec.size(); ++_ind)
_vec[_ind] = (*this)[_ind];
return _vec;
}

private: /// Ops and expr are assumed cheap to copy.


Ops _ops;
lExpr _lxpr;
rExpr _rxpr;
};

/// -----------------------------------------
/// Section 4.
///
/// The following two structs defines algebraic operations on PAEs: here only vector
/// plus and vector inner product are implemented.
///
/// First, some element-wise operations are defined : in other words, vec_plus and
/// vec_prod acts on elements in Vectors, but not whole Vectors.
///
/// Then, operator + & * are overloaded on PAEs, such that: + & * operations on PAEs
/// also return PAEs.
///
/// -----------------------------------------

/// Element-wise plus operation.


struct vec_plus_t
{
constexpr explicit vec_plus_t() = default;
template<typename LType, typename RType>
auto operator()(const LType &lhs, const RType &rhs) const
{ return lhs+rhs; }
};

/// Element-wise inner product operation.


struct vec_prod_t
{
constexpr explicit vec_prod_t() = default;
template<typename LType, typename RType>
auto operator()(const LType &lhs, const RType &rhs) const
{ return lhs*rhs; }
};

/// Constant plus and inner product operator objects.


constexpr vec_plus_t vec_plus{};
constexpr vec_prod_t vec_prod{};

/// Plus operator overload on expressions: return binary expression.


template<typename lExpr, typename rExpr>

https://riptutorial.com/ 238
auto operator+(const lExpr &lhs, const rExpr &rhs)
{ return binary_ops<vec_plus_t,lExpr,rExpr>(vec_plus,lhs,rhs); }

/// Inner prod operator overload on expressions: return binary expression.


template<typename lExpr, typename rExpr>
auto operator*(const lExpr &lhs, const rExpr &rhs)
{ return binary_ops<vec_prod_t,lExpr,rExpr>(vec_prod,lhs,rhs); }

} //!expr

#endif //!EXPR_EXPR

File main.cc : test src file

# include <chrono>
# include <iomanip>
# include <iostream>
# include "vec.hh"
# include "expr.hh"
# include "boost/core/demangle.hpp"

int main()
{
using dtype = float;
constexpr int size = 5e7;

std::vector<dtype> _vec1(size);
std::vector<dtype> _vec2(size);
std::vector<dtype> _vec3(size);

// ... Initialize vectors' contents.

Vector<dtype> vec1(std::move(_vec1));
Vector<dtype> vec2(std::move(_vec2));
Vector<dtype> vec3(std::move(_vec3));

unsigned long start_ms_no_ets =


std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now().time_since_epoch()).count();
std::cout << "\nNo-ETs evaluation starts.\n";

Vector<dtype> result_no_ets = vec1 + (vec2*vec3);

unsigned long stop_ms_no_ets =


std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now().time_since_epoch()).count();
std::cout << std::setprecision(6) << std::fixed
<< "No-ETs. Time eclapses: " << (stop_ms_no_ets-start_ms_no_ets)/1000.0
<< " s.\n" << std::endl;

unsigned long start_ms_ets =


std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now().time_since_epoch()).count();
std::cout << "Evaluation using ETs starts.\n";

https://riptutorial.com/ 239
expr::terminal<Vector<dtype>> vec4(vec1);
expr::terminal<Vector<dtype>> vec5(vec2);
expr::terminal<Vector<dtype>> vec6(vec3);

Vector<dtype> result_ets = (vec4 + vec5*vec6);

unsigned long stop_ms_ets =


std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now().time_since_epoch()).count();
std::cout << std::setprecision(6) << std::fixed
<< "With ETs. Time eclapses: " << (stop_ms_ets-start_ms_ets)/1000.0
<< " s.\n" << std::endl;

auto ets_ret_type = (vec4 + vec5*vec6);


std::cout << "\nETs result's type:\n";
std::cout << boost::core::demangle( typeid(decltype(ets_ret_type)).name() ) << '\n';

return 0;
}

Here's one possible output when compiled with -O3 -std=c++14 using GCC 5.3:

ctor called.
ctor called.
ctor called.

No-ETs evaluation starts.


ctor called.
ctor called.
No-ETs. Time eclapses: 0.571000 s.

Evaluation using ETs starts.


ctor called.
With ETs. Time eclapses: 0.164000 s.

ETs result's type:


expr::binary_ops<expr::vec_plus_t, expr::terminal<Vector<float> >,
expr::binary_ops<expr::vec_prod_t, expr::terminal<Vector<float> >,
expr::terminal<Vector<float> > > >

The observations are:

• Using ETs achieves rather significant performance boost in this case ( > 3x).
• Creation of temporary Vector object is eliminated. As in the ETs case, ctor is called only
once.
• Boost::demangle was used to visualize the type of ETs return before conversion: it clearly
constructed exactly the same expression graph demonstrated above.

Draw-backs and caveats

• An obvious disadvantage of ETs is the learning curve, the complexity of implementation and
code-maintenance difficulty. In the above example where only element-wise operations are
considered, the implementation contains already enormous amount of boilerplates, let alone

https://riptutorial.com/ 240
in real world, where more complex algebraic expressions occur in every computation and
element-wise independence no longer hold (for example matrix multiplication), the difficulty
will be exponential.

• Another caveat of using ETs is that they do play well with the auto keyword. As mentioned
above, PAEs are essentially proxies: and proxies basically do not play well with auto.
Consider the following example:

auto result = ...; // Some expensive expression:


// auto returns the expr graph,
// NOT the computed value.
for(auto i = 0; i < 100; ++i)
ScalrType value = result* ... // Some other expensive computations using result.

Here in each iteration of the for loop, result will be re-evaluated, since the expression graph
instead of the computed value is passed to the for loop.

Existing libraries implementing ETs

• boost::proto is a powerful library letting you define your own rules & grammars for your own
expressions and execute using ETs.
• Eigen is a library for linear algebra that implements various algebraic computations
efficiently using ETs.

A basic example illustrating expression templates

An expression template is a compile-time optimization technique used mostly in scientific


computing. It's main purpose is to avoid unnecessary temporaries and optimize loop calculations
using a single pass (typically when performing operations on numerical aggregates). Expression
templates were initially devised in order to circumvent the inefficiencies of naïve operator
overloading when implementing numerical Array or Matrix types. An equivalent terminology for
expression templates has been introduced by Bjarne Stroustrup, who calls them "fused
operations" in the latest version of his book, "The C++ Programming Language".

Before actually diving into expression templates, you should understand why you need them in the
first place. To illustrate this, consider the very simple Matrix class given below:

template <typename T, std::size_t COL, std::size_t ROW>


class Matrix {
public:
using value_type = T;

Matrix() : values(COL * ROW) {}

static size_t cols() { return COL; }


static size_t rows() { return ROW; }

const T& operator()(size_t x, size_t y) const { return values[y * COL + x]; }


T& operator()(size_t x, size_t y) { return values[y * COL + x]; }

https://riptutorial.com/ 241
private:
std::vector<T> values;
};

template <typename T, std::size_t COL, std::size_t ROW>


Matrix<T, COL, ROW>
operator+(const Matrix<T, COL, ROW>& lhs, const Matrix<T, COL, ROW>& rhs)
{
Matrix<T, COL, ROW> result;

for (size_t y = 0; y != lhs.rows(); ++y) {


for (size_t x = 0; x != lhs.cols(); ++x) {
result(x, y) = lhs(x, y) + rhs(x, y);
}
}
return result;
}

Given the previous class definition, you can now write Matrix expressions such as:

const std::size_t cols = 2000;


const std::size_t rows = 1000;

Matrix<double, cols, rows> a, b, c;

// initialize a, b & c
for (std::size_t y = 0; y != rows; ++y) {
for (std::size_t x = 0; x != cols; ++x) {
a(x, y) = 1.0;
b(x, y) = 2.0;
c(x, y) = 3.0;
}
}

Matrix<double, cols, rows> d = a + b + c; // d(x, y) = 6

As illustrated above, being able to overload operator+() provides you with a notation which mimics
the natural mathematical notation for matrices.

Unfortunately, the previous implementation is also highly inefficient compared to an equivalent


"hand-crafted" version.

To understand why, you have to consider what happens when you write an expression such as
Matrix d = a + b + c. This in fact expands to ((a + b) + c) or operator+(operator+(a, b), c). In
other words, the loop inside operator+() is executed twice, whereas it could have been easily
performed in a single pass. This also results in 2 temporaries being created, which further
degrades performance. In essence, by adding the flexibility to use a notation close to its
mathematical counterpart, you have also made the Matrix class highly inefficient.

For example, without operator overloading, you could implement a far more efficient Matrix
summation using a single pass:

template<typename T, std::size_t COL, std::size_t ROW>


Matrix<T, COL, ROW> add3(const Matrix<T, COL, ROW>& a,
const Matrix<T, COL, ROW>& b,

https://riptutorial.com/ 242
const Matrix<T, COL, ROW>& c)
{
Matrix<T, COL, ROW> result;
for (size_t y = 0; y != ROW; ++y) {
for (size_t x = 0; x != COL; ++x) {
result(x, y) = a(x, y) + b(x, y) + c(x, y);
}
}
return result;
}

The previous example however has its own disadvantages because it creates a far more
convoluted interface for the Matrix class (you would have to consider methods such as
Matrix::add2(), Matrix::AddMultiply() and so on).

Instead let us take a step back and see how we can adapt operator overloading to perform in a
more efficient way

The problem stems from the fact that the expression Matrix d = a + b + c is evaluated too
"eagerly" before you have had an opportunity to build the entire expression tree. In other words,
what you really want to achieve is to evaluate a + b + c in one pass and only once you actually
need to assign the resulting expressing to d.

This is the core idea behind expression templates: instead of having operator+() evaluate
immediately the result of adding two Matrix instances, it will return an "expression template" for
future evaluation once the entire expression tree has been built.

For example, here is a possible implementation for an expression template corresponding to the
summation of 2 types:

template <typename LHS, typename RHS>


class MatrixSum
{
public:
using value_type = typename LHS::value_type;

MatrixSum(const LHS& lhs, const RHS& rhs) : rhs(rhs), lhs(lhs) {}

value_type operator() (int x, int y) const {


return lhs(x, y) + rhs(x, y);
}
private:
const LHS& lhs;
const RHS& rhs;
};

And here is the updated version of operator+()

template <typename LHS, typename RHS>


MatrixSum<LHS, RHS> operator+(const LHS& lhs, const LHS& rhs) {
return MatrixSum<LHS, RHS>(lhs, rhs);
}

As you can see, operator+() no longer returns an "eager evaluation" of the result of adding 2

https://riptutorial.com/ 243
Matrix instances (which would be another Matrix instance), but instead an expression template
representing the addition operation. The most important point to keep in mind is that the
expression has not been evaluated yet. It merely holds references to its operands.

In fact, nothing stops you from instantiating the MatrixSum<> expression template as follows:

MatrixSum<Matrix<double>, Matrix<double> > SumAB(a, b);

You can however at a later stage, when you actually need the result of the summation, evaluate
the expression d = a + b as follows:

for (std::size_t y = 0; y != a.rows(); ++y) {


for (std::size_t x = 0; x != a.cols(); ++x) {
d(x, y) = SumAB(x, y);
}
}

As you can see, another benefit of using an expression template, is that you have basically
managed to evaluate the sum of a and b and assign it to d in a single pass.

Also, nothing stops you from combining multiple expression templates. For example, a + b + c
would result in the following expression template:

MatrixSum<MatrixSum<Matrix<double>, Matrix<double> >, Matrix<double> > SumABC(SumAB, c);

And here again you can evaluate the final result using a single pass:

for (std::size_t y = 0; y != a.rows(); ++y) {


for (std::size_t x = 0; x != a.cols(); ++x) {
d(x, y) = SumABC(x, y);
}
}

Finally, the last piece of the puzzle is to actually plug your expression template into the Matrix
class. This is essentially achieved by providing an implementation for Matrix::operator=(), which
takes the expression template as an argument and evaluates it in one pass, as you did "manually"
before:

template <typename T, std::size_t COL, std::size_t ROW>


class Matrix {
public:
using value_type = T;

Matrix() : values(COL * ROW) {}

static size_t cols() { return COL; }


static size_t rows() { return ROW; }

const T& operator()(size_t x, size_t y) const { return values[y * COL + x]; }


T& operator()(size_t x, size_t y) { return values[y * COL + x]; }

template <typename E>

https://riptutorial.com/ 244
Matrix<T, COL, ROW>& operator=(const E& expression) {
for (std::size_t y = 0; y != rows(); ++y) {
for (std::size_t x = 0; x != cols(); ++x) {
values[y * COL + x] = expression(x, y);
}
}
return *this;
}

private:
std::vector<T> values;
};

Read Expression templates online: https://riptutorial.com/cplusplus/topic/3404/expression-


templates

https://riptutorial.com/ 245
Chapter 43: File I/O
Introduction
C++ file I/O is done via streams. The key abstractions are:

std::istream for reading text.

std::ostream for writing text.

std::streambuf for reading or writing characters.

Formatted input uses operator>>.

Formatted output uses operator<<.

Streams use std::locale, e.g., for details of the formatting and for translation between external
encodings and the internal encoding.

More on streams: <iostream> Library

Examples
Opening a file

Opening a file is done in the same way for all 3 file streams (ifstream, ofstream, and fstream).

You can open the file directly in the constructor:

std::ifstream ifs("foo.txt"); // ifstream: Opens file "foo.txt" for reading only.

std::ofstream ofs("foo.txt"); // ofstream: Opens file "foo.txt" for writing only.

std::fstream iofs("foo.txt"); // fstream: Opens file "foo.txt" for reading and writing.

Alternatively, you can use the file stream's member function open():

std::ifstream ifs;
ifs.open("bar.txt"); // ifstream: Opens file "bar.txt" for reading only.

std::ofstream ofs;
ofs.open("bar.txt"); // ofstream: Opens file "bar.txt" for writing only.

std::fstream iofs;
iofs.open("bar.txt"); // fstream: Opens file "bar.txt" for reading and writing.

You should always check if a file has been opened successfully (even when writing). Failures can
include: the file doesn't exist, file hasn't the right access rights, file is already in use, disk errors
occurred, drive disconnected ... Checking can be done as follows:

https://riptutorial.com/ 246
// Try to read the file 'foo.txt'.
std::ifstream ifs("fooo.txt"); // Note the typo; the file can't be opened.

// Check if the file has been opened successfully.


if (!ifs.is_open()) {
// The file hasn't been opened; take appropriate actions here.
throw CustomException(ifs, "File could not be opened");
}

When file path contains backslashes (for example, on Windows system) you should properly
escape them:

// Open the file 'c:\folder\foo.txt' on Windows.


std::ifstream ifs("c:\\folder\\foo.txt"); // using escaped backslashes

C++11

or use raw literal:

// Open the file 'c:\folder\foo.txt' on Windows.


std::ifstream ifs(R"(c:\folder\foo.txt)"); // using raw literal

or use forward slashes instead:

// Open the file 'c:\folder\foo.txt' on Windows.


std::ifstream ifs("c:/folder/foo.txt");

C++11

If you want to open file with non-ASCII characters in path on Windows currently you can use non-
standard wide character path argument:

// Open the file 'пример\foo.txt' on Windows.


std::ifstream ifs(LR"(пример\foo.txt)"); // using wide characters with raw literal

Reading from a file

There are several ways to read data from a file.

If you know how the data is formatted, you can use the stream extraction operator (>>). Let's
assume you have a file named foo.txt which contains the following data:

John Doe 25 4 6 1987


Jane Doe 15 5 24 1976

Then you can use the following code to read that data from the file:

// Define variables.
std::ifstream is("foo.txt");
std::string firstname, lastname;
int age, bmonth, bday, byear;

https://riptutorial.com/ 247
// Extract firstname, lastname, age, bday month, bday day, and bday year in that order.
// Note: '>>' returns false if it reached EOF (end of file) or if the input data doesn't
// correspond to the type of the input variable (for example, the string "foo" can't be
// extracted into an 'int' variable).
while (is >> firstname >> lastname >> age >> bmonth >> bday >> byear)
// Process the data that has been read.

The stream extraction operator >> extracts every character and stops if it finds a character that
can't be stored or if it is a special character:

• For string types, the operator stops at a whitespace () or at a newline (\n).


• For numbers, the operator stops at a non-number character.

This means that the following version of the file foo.txt will also be successfully read by the
previous code:

John
Doe 25
4 6 1987

Jane
Doe
15 5
24
1976

The stream extraction operator >> always returns the stream given to it. Therefore, multiple
operators can be chained together in order to read data consecutively. However, a stream can
also be used as a Boolean expression (as shown in the while loop in the previous code). This is
because the stream classes have a conversion operator for the type bool. This bool() operator will
return true as long as the stream has no errors. If a stream goes into an error state (for example,
because no more data can be extracted), then the bool() operator will return false. Therefore, the
while loop in the previous code will be exited after the input file has been read to its end.

If you wish to read an entire file as a string, you may use the following code:

// Opens 'foo.txt'.
std::ifstream is("foo.txt");
std::string whole_file;

// Sets position to the end of the file.


is.seekg(0, std::ios::end);

// Reserves memory for the file.


whole_file.reserve(is.tellg());

// Sets position to the start of the file.


is.seekg(0, std::ios::beg);

// Sets contents of 'whole_file' to all characters in the file.


whole_file.assign(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>());

https://riptutorial.com/ 248
This code reserves space for the string in order to cut down on unneeded memory allocations.

If you want to read a file line by line, you can use the function getline():

std::ifstream is("foo.txt");

// The function getline returns false if there are no more lines.


for (std::string str; std::getline(is, str);) {
// Process the line that has been read.
}

If you want to read a fixed number of characters, you can use the stream's member function read()
:

std::ifstream is("foo.txt");
char str[4];

// Read 4 characters from the file.


is.read(str, 4);

After executing a read command, you should always check if the error state flag failbit has been
set, as it indicates whether the operation failed or not. This can be done by calling the file stream's
member function fail():

is.read(str, 4); // This operation might fail for any reason.

if (is.fail())
// Failed to read!

Writing to a file

There are several ways to write to a file. The easiest way is to use an output file stream (ofstream)
together with the stream insertion operator (<<):

std::ofstream os("foo.txt");
if(os.is_open()){
os << "Hello World!";
}

Instead of <<, you can also use the output file stream's member function write():

std::ofstream os("foo.txt");
if(os.is_open()){
char data[] = "Foo";

// Writes 3 characters from data -> "Foo".


os.write(data, 3);
}

After writing to a stream, you should always check if error state flag badbit has been set, as it
indicates whether the operation failed or not. This can be done by calling the output file stream's
member function bad():

https://riptutorial.com/ 249
os << "Hello Badbit!"; // This operation might fail for any reason.
if (os.bad())
// Failed to write!

Opening modes

When creating a file stream, you can specify an opening mode. An opening mode is basically a
setting to control how the stream opens the file.

(All modes can be found in the std::ios namespace.)

An opening mode can be provided as second parameter to the constructor of a file stream or to its
open() member function:

std::ofstream os("foo.txt", std::ios::out | std::ios::trunc);

std::ifstream is;
is.open("foo.txt", std::ios::in | std::ios::binary);

It is to be noted that you have to set ios::in or ios::out if you want to set other flags as they are
not implicitly set by the iostream members although they have a correct default value.

If you don't specify an opening mode, then the following default modes are used:

• ifstream - in
• ofstream - out
• fstream - in and out

The file opening modes that you may specify by design are:

Mode Meaning For Description

app append Output Appends data at the end of the file.

binary binary Input/Output Input and output is done in binary.

in input Input Opens the file for reading.

out output Output Opens the file for writing.

trunc truncate Input/Output Removes contents of the file when opening.

ate at end Input Goes to the end of the file when opening.

Note: Setting the binary mode lets the data be read/written exactly as-is; not setting it enables the
translation of the newline '\n' character to/from a platform specific end of line sequence.

For example on Windows the end of line sequence is CRLF ("\r\n").


Write: "\n" => "\r\n"
Read: "\r\n" => "\n"

https://riptutorial.com/ 250
Closing a file

Explicitly closing a file is rarely necessary in C++, as a file stream will automatically close its
associated file in its destructor. However, you should try to limit the lifetime of a file stream object,
so that it does not keep the file handle open longer than necessary. For example, this can be done
by putting all file operations into an own scope ({}):

std::string const prepared_data = prepare_data();


{
// Open a file for writing.
std::ofstream output("foo.txt");

// Write data.
output << prepared_data;
} // The ofstream will go out of scope here.
// Its destructor will take care of closing the file properly.

Calling close() explicitly is only necessary if you want to reuse the same fstream object later, but
don't want to keep the file open in between:

// Open the file "foo.txt" for the first time.


std::ofstream output("foo.txt");

// Get some data to write from somewhere.


std::string const prepared_data = prepare_data();

// Write data to the file "foo.txt".


output << prepared_data;

// Close the file "foo.txt".


output.close();

// Preparing data might take a long time. Therefore, we don't open the output file stream
// before we actually can write some data to it.
std::string const more_prepared_data = prepare_complex_data();

// Open the file "foo.txt" for the second time once we are ready for writing.
output.open("foo.txt");

// Write the data to the file "foo.txt".


output << more_prepared_data;

// Close the file "foo.txt" once again.


output.close();

Flushing a stream

File streams are buffered by default, as are many other types of streams. This means that writes
to the stream may not cause the underlying file to change immediately. In oder to force all buffered
writes to take place immediately, you can flush the stream. You can do this either directly by
invoking the flush() method or through the std::flush stream manipulator:

std::ofstream os("foo.txt");
os << "Hello World!" << std::flush;

https://riptutorial.com/ 251
char data[3] = "Foo";
os.write(data, 3);
os.flush();

There is a stream manipulator std::endl that combines writing a newline with flushing the stream:

// Both following lines do the same thing


os << "Hello World!\n" << std::flush;
os << "Hello world!" << std::endl;

Buffering can improve the performance of writing to a stream. Therefore, applications that do a lot
of writing should avoid flushing unnecessarily. Contrary, if I/O is done infrequently, applications
should consider flushing frequently in order to avoid data getting stuck in the stream object.

Reading an ASCII file into a std::string

std::ifstream f("file.txt");

if (f)
{
std::stringstream buffer;
buffer << f.rdbuf();
f.close();

// The content of "file.txt" is available in the string `buffer.str()`


}

The rdbuf() method returns a pointer to a streambuf that can be pushed into buffer via the
stringstream::operator<< member function.

Another possibility (popularized in Effective STL by Scott Meyers) is:

std::ifstream f("file.txt");

if (f)
{
std::string str((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());

// Operations on `str`...
}

This is nice because requires little code (and allows reading a file directly into any STL container,
not only strings) but can be slow for big files.

NOTE: the extra parentheses around the first argument to the string constructor are essential to
prevent the most vexing parse problem.

Last but not least:

https://riptutorial.com/ 252
std::ifstream f("file.txt");

if (f)
{
f.seekg(0, std::ios::end);
const auto size = f.tellg();

std::string str(size, ' ');


f.seekg(0);
f.read(&str[0], size);
f.close();

// Operations on `str`...
}

which is probably the fastest option (among the three proposed).

Reading a file into a container

In the example below we use std::string and operator>> to read items from the file.

std::ifstream file("file3.txt");

std::vector<std::string> v;

std::string s;
while(file >> s) // keep reading until we run out
{
v.push_back(s);
}

In the above example we are simply iterating through the file reading one "item" at a time using
operator>>. This same affect can be achieved using the std::istream_iterator which is an input
iterator that reads one "item" at a time from the stream. Also most containers can be constructed
using two iterators so we can simplify the above code to:

std::ifstream file("file3.txt");

std::vector<std::string> v(std::istream_iterator<std::string>{file},
std::istream_iterator<std::string>{});

We can extend this to read any object types we like by simply specifying the object we want to
read as the template parameter to the std::istream_iterator. Thus we can simply extend the
above to read lines (rather than words) like this:

// Unfortunately there is no built in type that reads line using >>


// So here we build a simple helper class to do it. That will convert
// back to a string when used in string context.
struct Line
{
// Store data here
std::string data;
// Convert object to string
operator std::string const&() const {return data;}

https://riptutorial.com/ 253
// Read a line from a stream.
friend std::istream& operator>>(std::istream& stream, Line& line)
{
return std::getline(stream, line.data);
}
};

std::ifstream file("file3.txt");

// Read the lines of a file into a container.


std::vector<std::string> v(std::istream_iterator<Line>{file},
std::istream_iterator<Line>{});

Reading a `struct` from a formatted text file.

C++11

struct info_type
{
std::string name;
int age;
float height;

// we define an overload of operator>> as a friend function which


// gives in privileged access to private data members
friend std::istream& operator>>(std::istream& is, info_type& info)
{
// skip whitespace
is >> std::ws;
std::getline(is, info.name);
is >> info.age;
is >> info.height;
return is;
}
};

void func4()
{
auto file = std::ifstream("file4.txt");

std::vector<info_type> v;

for(info_type info; file >> info;) // keep reading until we run out
{
// we only get here if the read succeeded
v.push_back(info);
}

for(auto const& info: v)


{
std::cout << " name: " << info.name << '\n';
std::cout << " age: " << info.age << " years" << '\n';
std::cout << "height: " << info.height << "lbs" << '\n';
std::cout << '\n';
}
}

file4.txt

https://riptutorial.com/ 254
Wogger Wabbit
2
6.2
Bilbo Baggins
111
81.3
Mary Poppins
29
154.8

Output:

name: Wogger Wabbit


age: 2 years
height: 6.2lbs

name: Bilbo Baggins


age: 111 years
height: 81.3lbs

name: Mary Poppins


age: 29 years
height: 154.8lbs

Copying a file

std::ifstream src("source_filename", std::ios::binary);


std::ofstream dst("dest_filename", std::ios::binary);
dst << src.rdbuf();

C++17

With C++17 the standard way to copy a file is including the <filesystem> header and using
copy_file:

std::fileystem::copy_file("source_filename", "dest_filename");

The filesystem library was originally developed as boost.filesystem and finally merged to ISO C++
as of C++17.

Checking end of file inside a loop condition, bad practice?

eof returns true only after reading the end of file. It does NOT indicate that the next read will be
the end of stream.

while (!f.eof())
{
// Everything is OK

f >> buffer;

// What if *only* now the eof / fail bit is set?

https://riptutorial.com/ 255
/* Use `buffer` */
}

You could correctly write:

while (!f.eof())
{
f >> buffer >> std::ws;

if (f.fail())
break;

/* Use `buffer` */
}

but

while (f >> buffer)


{
/* Use `buffer` */
}

is simpler and less error prone.

Further references:

• std::ws:discards leading whitespace from an input stream


• std::basic_ios::fail: returns true if an error has occurred on the associated stream

Writing files with non-standard locale settings

If you need to write a file using different locale settings to the default, you can use std::locale and
std::basic_ios::imbue() to do that for a specific file stream:

Guidance for use:

• You should always apply a local to a stream before opening the file.
• Once the stream has been imbued you should not change the locale.

Reasons for Restrictions: Imbuing a file stream with a locale has undefined behavior if the
current locale is not state independent or not pointing at the beginning of the file.

UTF-8 streams (and others) are not state independent. Also a file stream with a UTF-8 locale may
try and read the BOM marker from the file when it is opened; so just opening the file may read
characters from the file and it will not be at the beginning.

#include <iostream>
#include <fstream>
#include <locale>

int main()
{

https://riptutorial.com/ 256
std::cout << "User-preferred locale setting is "
<< std::locale("").name().c_str() << std::endl;

// Write a floating-point value using the user's preferred locale.


std::ofstream ofs1;
ofs1.imbue(std::locale(""));
ofs1.open("file1.txt");
ofs1 << 78123.456 << std::endl;

// Use a specific locale (names are system-dependent)


std::ofstream ofs2;
ofs2.imbue(std::locale("en_US.UTF-8"));
ofs2.open("file2.txt");
ofs2 << 78123.456 << std::endl;

// Switch to the classic "C" locale


std::ofstream ofs3;
ofs3.imbue(std::locale::classic());
ofs3.open("file3.txt");
ofs3 << 78123.456 << std::endl;
}

Explicitly switching to the classic "C" locale is useful if your program uses a different default locale
and you want to ensure a fixed standard for reading and writing files. With a "C" preferred locale,
the example writes

78,123.456
78,123.456
78123.456

If, for example, the preferred locale is German and hence uses a different number format, the
example writes

78 123,456
78,123.456
78123.456

(note the decimal comma in the first line).

Read File I/O online: https://riptutorial.com/cplusplus/topic/496/file-i-o

https://riptutorial.com/ 257
Chapter 44: Floating Point Arithmetic
Examples
Floating Point Numbers are Weird

The first mistake that nearly every single programmer makes is presuming that this code will work
as intended:

float total = 0;
for(float a = 0; a != 2; a += 0.01f) {
total += a;
}

The novice programmer assumes that this will sum up every single number in the range 0, 0.01,
0.02, 0.03, ..., 1.97, 1.98, 1.99, to yield the result 199—the mathematically correct answer.

Two things happen that make this untrue:

1. The program as written never concludes. a never becomes equal to 2, and the loop never
terminates.
2. If we rewrite the loop logic to check a < 2 instead, the loop terminates, but the total ends up
being something different from 199. On IEEE754-compliant machines, it will often sum up to
about 201 instead.

The reason that this happens is that Floating Point Numbers represent Approximations of
their assigned values.

The classical example is the following computation:

double a = 0.1;
double b = 0.2;
double c = 0.3;
if(a + b == c)
//This never prints on IEEE754-compliant machines
std::cout << "This Computer is Magic!" << std::endl;
else
std::cout << "This Computer is pretty normal, all things considered." << std::endl;

Though what we the programmer see is three numbers written in base10, what the compiler (and
the underlying hardware) see are binary numbers. Because 0.1, 0.2, and 0.3 require perfect
division by 10—which is quite easy in a base-10 system, but impossible in a base-2 system—these
numbers have to be stored in imprecise formats, similar to how the number 1/3 has to be stored in
the imprecise form 0.333333333333333... in base-10.

//64-bit floats have 53 digits of precision, including the whole-number-part.


double a = 0011111110111001100110011001100110011001100110011001100110011010; //imperfect
representation of 0.1
double b = 0011111111001001100110011001100110011001100110011001100110011010; //imperfect

https://riptutorial.com/ 258
representation of 0.2
double c = 0011111111010011001100110011001100110011001100110011001100110011; //imperfect
representation of 0.3
double a + b = 0011111111010011001100110011001100110011001100110011001100110100; //Note that
this is not quite equal to the "canonical" 0.3!

Read Floating Point Arithmetic online: https://riptutorial.com/cplusplus/topic/5115/floating-point-


arithmetic

https://riptutorial.com/ 259
Chapter 45: Flow Control
Remarks
Check out the loops topic for the different kind of loops.

Examples
case

Introduces a case label of a switch statement. The operand must be a constant expression and
match the switch condition in type. When the switch statement is executed, it will jump to the case
label with operand equal to the condition, if any.

char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}

switch

According to the C++ standard,

The switch statement causes control to be transferred to one of several statements


depending on the value of a condition.

The keyword switch is followed by a parenthesized condition and a block, which may contain case
labels and an optional default label. When the switch statement is executed, control will be
transferred either to a case label with a value matching that of the condition, if any, or to the default
label, if any.

The condition must be an expression or a declaration, which has either integer or enumeration
type, or a class type with a conversion function to integer or enumeration type.

char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;

https://riptutorial.com/ 260
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}

catch

The catch keyword introduces an exception handler, that is, a block into which control will be
transferred when an exception of compatible type is thrown. The catch keyword is followed by a
parenthesized exception declaration, which is similar in form to a function parameter declaration:
the parameter name may be omitted, and the ellipsis ... is allowed, which matches any type. The
exception handler will only handle the exception if its declaration is compatible with the type of the
exception. For more details, see catching exceptions.

try {
std::vector<int> v(N);
// do something
} catch (const std::bad_alloc&) {
std::cout << "failed to allocate memory for vector!" << std::endl;
} catch (const std::runtime_error& e) {
std::cout << "runtime error: " << e.what() << std::endl;
} catch (...) {
std::cout << "unexpected exception!" << std::endl;
throw;
}

default

In a switch statement, introduces a label that will be jumped to if the condition's value is not equal
to any of the case labels' values.

char c = getchar();
bool confirmed;
switch (c) {
case 'y':
confirmed = true;
break;
case 'n':
confirmed = false;
break;
default:
std::cout << "invalid response!\n";
abort();
}

C++11

Defines a default constructor, copy constructor, move constructor, destructor, copy assignment
operator, or move assignment operator to have its default behaviour.

https://riptutorial.com/ 261
class Base {
// ...
// we want to be able to delete derived classes through Base*,
// but have the usual behaviour for Base's destructor.
virtual ~Base() = default;
};

if

Introduces an if statement. The keyword if must be followed by a parenthesized condition, which


can be either an expression or a declaration. If the condition is truthy, the substatement after the
condition will be executed.

int x;
std::cout << "Please enter a positive number." << std::endl;
std::cin >> x;
if (x <= 0) {
std::cout << "You didn't enter a positive number!" << std::endl;
abort();
}

else

The first substatement of an if statement may be followed by the keyword else. The substatement
after the else keyword will be executed when the condition is falsey (that is, when the first
substatement is not executed).

int x;
std::cin >> x;
if (x%2 == 0) {
std::cout << "The number is even\n";
} else {
std::cout << "The number is odd\n";
}

goto

Jumps to a labelled statement, which must be located in the current function.

bool f(int arg) {


bool result = false;
hWidget widget = get_widget(arg);
if (!g()) {
// we can't continue, but must do cleanup still
goto end;
}
// ...
result = true;
end:
release_widget(widget);
return result;
}

https://riptutorial.com/ 262
return

Returns control from a function to its caller.

If return has an operand, the operand is converted to the function's return type, and the converted
value is returned to the caller.

int f() {
return 42;
}
int x = f(); // x is 42
int g() {
return 3.14;
}
int y = g(); // y is 3

If return does not have an operand, the function must have void return type. As a special case, a
void-returning function can also return an expression if the expression has type void.

void f(int x) {
if (x < 0) return;
std::cout << sqrt(x);
}
int g() { return 42; }
void h() {
return f(); // calls f, then returns
return g(); // ill-formed
}

When main returns, std::exit is implicitly called with the return value, and the value is thus
returned to the execution environment. (However, returning from main destroys automatic local
variables, while calling std::exit directly does not.)

int main(int argc, char** argv) {


if (argc < 2) {
std::cout << "Missing argument\n";
return EXIT_FAILURE; // equivalent to: exit(EXIT_FAILURE);
}
}

throw

1. When throw occurs in an expression with an operand, its effect is to throw an exception,
which is a copy of the operand.

void print_asterisks(int count) {


if (count < 0) {
throw std::invalid_argument("count cannot be negative!");
}
while (count--) { putchar('*'); }
}

https://riptutorial.com/