0% found this document useful (0 votes)
32 views

0928 Modern C Tutorial

This document is a table of contents for a book about modern C++. It lists chapter titles and section headings that will explain C++ language features from C++11, 14, 17 and 20, including language enhancements, runtime features, containers, smart pointers and regular expressions. The document is licensed under a Creative Commons license that allows non-commercial sharing and distribution with attribution.

Uploaded by

Cristian Costea
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

0928 Modern C Tutorial

This document is a table of contents for a book about modern C++. It lists chapter titles and section headings that will explain C++ language features from C++11, 14, 17 and 20, including language enhancements, runtime features, containers, smart pointers and regular expressions. The document is licensed under a Creative Commons license that allows non-commercial sharing and distribution with attribution.

Uploaded by

Cristian Costea
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Modern C++ Tutorial: C++11/14/17/20 On the Fly

Changkun Ou ([email protected])

Last update: February 23, 2020

Notice

The content in this PDF file may outdated, please check our website or GitHub repository for the latest
book updates.

License
This work was written by Ou Changkun and licensed under a Creative Commons
Attribution-NonCommercial-NoDerivatives 4.0 International License.
http://creativecommons.org/licenses/by-nc-nd/4.0/

1
2
CONTENTS CONTENTS

Contents

Preface 8

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Targets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Chapter 01: Towards Modern C++ 9

1.1 Deprecated Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1.2 Compatibilities with C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Chapter 02: Language Usability Enhancements 13

2.1 Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

nullptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

constexpr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

2.2 Variables and initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

if-switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Initializer list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Structured binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2.3 Type inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

auto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

decltype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

tail type inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

decltype(auto) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.4 Control flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

if constexpr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

Range-based for loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

2.5 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

3
CONTENTS CONTENTS

Extern templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

The “>” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Type alias templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Default template parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Variadic templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Fold expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Non-type template parameter deduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

2.6 Object-oriented . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Delegate constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Inheritance constructor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

Explicit virtual function overwrite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Explicit delete default function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

Strongly typed enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

Chapter 03: Language Runtime Enhancements 36

3.1 Lambda Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Generic Lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

3.2 Function Object Wrapper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

std::function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

std::bind and std::placeholder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3.3 rvalue Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

lvalue, rvalue, prvalue, xvalue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

rvalue reference and lvalue reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Move semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Perfect forwarding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4
CONTENTS CONTENTS

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Chapter 04 Containers 48

4.1 Linear Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

std::array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

std::forward_list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

4.2 Unordered Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

4.3 Tuples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

Basic Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

Runtime Indexing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53

Merge and Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

Chapter 05 Smart Pointers and Memory Management 54

5.1 RAII and Reference Counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

5.2 std::shared_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

5.3 std::unique_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

5.4 std::weak_ptr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Chapter 06 Regular Expression 60

6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Ordinary characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Special characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

Quantifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

6.2 std::regex and Its Related . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63

Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

5
CONTENTS CONTENTS

Chapter 07 Parallelism and Concurrency 66

7.1 Basic of Parallelism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.2 Mutex and Critical Section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.3 Future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

7.4 Condition Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

7.5 Atomic Operation and Memory Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70

Atomic Operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

Concistency Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

Memory Orders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

Chapter 08 File System 78

8.1 Document and Link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

8.2 std::filesystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

Chapter 09 Minor Features 79

9.1 New Type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

long long int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

9.2 noexcept and Its Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

9.3 Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Raw String Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Custom Literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

9.4 Memory Alignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Chapter 10 Outlook: Introduction of C++20 83

Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

6
CONTENTS CONTENTS

Contract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Coroutine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Further Readings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

Appendix 1: Further Study Materials 84

Appendix 2: Modern C++ Best Practices 85

Common Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Coding Style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Overall Performance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Code Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Maintainability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

7
PREFACE

Preface

Introduction

C++ user group is a fairly large. From the advent of C++98 to the official finalization of C++11,
it has accumulated over a decade. C++14/17 is an important complement and optimization for C++11,
and C++20 brings this language to the door of modernization. The extended features of all these new
standards are given to the C++ language. Infused with new vitality. C++ programmers, who are still
using traditional C++ (this book refers to C++98 and its previous C++ standards as traditional
C++), may even amzed by the fact that they are not using the same language while reading modern
C++ code.

Modern C++ (this book refers to C++11/14/17/20) introduces a lot of features into traditional
C++, which makes the whole C++ become language that modernized. Modern C++ not only enhances
the usability of the C++ language itself, but the modification of the auto keyword semantics gives us more
confidence in manipulating extremely complex template types. At the same time, a lot of enhancements
have been made to the language runtime. The emergence of Lambda expressions has made C++ have
the “closure” feature of “anonymous functions”, which is almost in modern programming languages (such
as Python/Swift/.. It has become commonplace, and the emergence of rvalue references has solved the
problem of temporary object efficiency that C++ has long been criticized.

C++17 is the direction that has been promoted by the C++ community in the past three years. It
also points out an important development direction of modern C++ programming. Although it does
not appear as much as C++11, it contains a large number of small and beautiful languages and features
(such as structured binding), and the appearance of these features once again corrects our programming
paradigm in C++.

Modern C++ also adds a lot of tools and methods to its own standard library, such as std::thread
at the level of the language itself, which supports concurrent programming and no longer depends on the
underlying system on different platforms. The API implements cross-platform support at the language
level; std::regex provides full regular expression support and more. C++98 has been proven to be a
very successful “paradigm”, and the emergence of modern C++ further promotes this paradigm, making
C++ a better language for system programming and library development. Concepts provide verification
on the compile-time of template parameters, further enhancing the usability of the language.

In conclusion, as an advocate and practitioner of C++, we always maintain an open mind to accept
new things, and we can promote the development of C++ faster, making this old and novel language
more vibrant.

Targets

• This book assumes that readers are already familiar with traditional C++ (i.e. C++98 or earlier),
at least they do not have any difficulty in reading traditional C++ code. In other words, those who
have long experience in traditional C++ and people who desire to quickly understand the features

8
Purpose CHAPTER 01: TOWARDS MODERN C++

of modern C++ in a short period of time are well suited to read the book;

• This book introduces to a certain extent of the dark magic of modern C++. However, these magics
are very limited, they are not suitable for readers who want to learn advanced C++. The purpose
of this book is offering a quick start for modern C++. Of course, advanced readers can also use
this book to review and examine themselves on modern C++.

Purpose

The book claims “On the Fly”. Its intent is to provide a comprehensive introduction to the relevant
features regarding modern C++ (before 2020s). Readers can choose interesting content according to
the following table of content to learn and quickly familiarize the new features you would like to learn.
Readers should aware that all of these features are not required. It should be leart when you really need
it.

At the same time, instead of grammar-only, the book introduces the historical background as simple
as possible of its technical requirements, which provides great help in understanding why these features
comes out.

In addition, The author would like to encourage that readers should be able to use modern C++
directly in their new projects and migrate their old projects to modern C++ gradually after read the
book.

Code

Each chapter of this book has a lot of code. If you encounter problems when writing your own code
with the introductory features of the book, you might as well read the source code attached to the book.
You can find the book here. All the code organized by chapter, the folder name is the chapter number.

Exercises

There are few exercises At the end of each chapter of the book. It is for testing whether you can
use the knowledge points in the current chapter. You can find the possible answer to the problem from
here. The folder name is the chapter number.

Chapter 01: Towards Modern C++

Compilation Environment: This book will use clang++ as the only compiler used, and always
use the -std=c++2a compilation flag in your code.

1 > clang ++ -v
2 Apple LLVM version 10.0.1 (clang -1001.0.46.4)
3 Target : x86_64 -apple - darwin18 .6.0

9
1.1 Deprecated Features CHAPTER 01: TOWARDS MODERN C++

4 Thread model : posix


5 InstalledDir : / Library / Developer / CommandLineTools /usr/bin

1.1 Deprecated Features

Before learning modern C++, let’s take a look at the main features that have been deprecated since
C++11:

Note: Deprecation is not completely unusable, it is only intended to imply that programmers
will disappear from future standards and should be avoided. However, the deprecated features
are still part of the standard library, and most of the features are actually “permanently”
reserved for compatibility reasons.

• The string literal constant is no longer allowed to be assigned to a char *. If you


need to assign and initialize a char * with a string literal constant, you should use
const char * or auto. cpp char *str = "hello world!"; // A deprecation warning will appear

• C++98 exception description, unexpected_handler, set_unexpected() and other related


features are deprecated and should use noexcept.

• auto_ptr is deprecated and unique_ptr should be used.

• register keyword is deprecated and can be used but no longer has any practical mean-
ing.

• The ++ operation of the bool type is deprecated.

• If a class has a destructor, the properties for which it generates copy constructors and
copy assignment operators are deprecated.

• C language style type conversion is deprecated (ie using (convert_type)) before variables,
and static_cast, reinterpret_cast, const_cast should be used for type conversion.

• In particular, some of the C standard libraries that can be used are deprecated in the
latest C++17 standard, such as <ccomplex>, <cstdalign>, <cstdbool> and <ctgmath> Wait

• … and many more

There are also other features such as parameter binding (C++11 provides std::bind and std::
function), export, and etc. are also deprecated. These features mentioned above If you have never
used or heard of it, please don’t try to understand them. You should move closer to the
new standard and learn new features directly. After all, technology is moving forward.

10
1.2 Compatibilities with C CHAPTER 01: TOWARDS MODERN C++

Figure 1: Figure 1.2: Compatabilities between ISO C and ISO C++

1.2 Compatibilities with C

For some force majeure and historical reasons, we had to use some C code (even old C code) in C++,
for example, Linux system calls. Before the advent of modern C++, most people talked about “what is
the difference between C and C++”. Generally speaking, in addition to answering the object-oriented
class features and the template features of generic programming, there is no other opinion, or even a
direct answer. “Almost” is also a lot of people. The Wayne diagram in Figure 1.2 roughly answers the
C and C++ related compatibility.

From now on, you should have the idea that “C++ is not a superset of C” in your mind (and not
from the beginning, later [References for further reading] (# further reading references) The difference
between C++98 and C99 is given). When writing C++, you should also avoid using program styles such
as void* whenever possible. When you have to use C, you should pay attention to the use of extern "C",
separate the C language code from the C++ code, and then unify the link, for instance:

1 // foo.h
2 #ifdef __cplusplus
3 extern "C" {
4 #endif
5

6 int add(int x, int y);


7

8 #ifdef __cplusplus
9 }
10 #endif

11
1.2 Compatibilities with C CHAPTER 01: TOWARDS MODERN C++

11

12 // foo.c
13 int add(int x, int y) {
14 return x+y;
15 }
16

17 // 1.1. cpp
18 # include "foo.h"
19 # include <iostream >
20 # include <functional >
21

22 int main () {
23 [out = std :: ref(std :: cout << " Result from C code: " << add (1, 2))](){
24 out.get () << ".\n";
25 }();
26 return 0;
27 }

You should first compile the C code with gcc:


1 gcc -c foo.c

Comple and output the foo.o file, and link the C++ code to the .o file using clang++ (or both
compile to .o and then unlink them together):
1 clang ++ 1.1. cpp foo.o -std=c++2a -o 1.1

Of course, you can use Makefile to compile the above code:


1 C = gcc
2 CXX = clang ++
3

4 SOURCE_C = foo.c
5 OBJECTS_C = foo.o
6

7 SOURCE_CXX = 1.1. cpp


8

9 TARGET = 1.1
10 LDFLAGS_COMMON = -std=c++2a
11

12 all:
13 (C) − c( SOURCE_C )
14 (CXX)( SOURCE_CXX ) (OBJECT SC )( LDFLAGS_COMMON ) -o (T ARGET )clean : rm − rf ∗ .o(
TARGET )

Note: Indentation in Makefile is a tab instead of a space character. If you copy this code di-
rectly into your editor, the tab may be automatically replaced. Please ensure the indentation

12
Further Readings CHAPTER 02: LANGUAGE USABILITY ENHANCEMENTS

in the Makefile. It is done by tabs.

If you don’t know the use of Makefile, it doesn’t matter. In this tutorial, you won’t build
code that is written too complicated. You can also read this book by simply using clang++ -
std=c++2a on the command line.

If you are new to modern C++, you probably still don’t understand the following small piece of
code above, namely:

1 [out = std :: ref(std :: cout << " Result from C code: " << add (1, 2))](){
2 out.get () << ".\n";
3 }();

Don’t worry at the moment, we will come to meet them in our later chapters.

Further Readings

• A Tour of C++ (2nd Edition) Bjarne Stroustrup History of C++


• C++ compiler support
• Incompatibilities Between ISO C and ISO C++

Chapter 02: Language Usability Enhancements

When we declare, define a variable or constant, and control the flow of code, object-oriented functions,
template programming, etc., before the runtime, it may happen when writing code or compiler compiling
code. To this end, we usually talk about language usability, which refers to the language behavior
that occurred before the runtime.

2.1 Constants

nullptr

The purpose of nullptr appears to replace NULL. In a sense, traditional C++ treats NULL and 0
as the same thing, depending on how the compiler defines NULL, and some compilers define NULL as
((void*)0) Some will define it directly as 0.

C++ ** does not allow ** to implicitly convert void * to other types. But if the compiler tries to
define NULL as ((void*)0), then in the following code:

1 char *ch = NULL;

C++ without the void * implicit conversion has to define NULL as 0. This still creates a new problem.
Defining NULL to 0 will cause the overloading feature in C++ to be confusing. Consider the following two
foo functions:

13
2.1 Constants CHAPTER 02: LANGUAGE USABILITY ENHANCEMENTS

1 void foo(char *);


2 void foo(int);

Then the foo(NULL); statement will call foo(int), which will cause the code to be counterintuitive.

To solve this problem, C++11 introduced the nullptr keyword, which is specifically used to distin-
guish null pointers, 0. The type of nullptr is nullptr_t, which can be implicitly converted to any pointer
or member pointer type, and can be compared equally or unequally with them.

You can try to compile the following code using clang++:

1 # include <iostream >


2 # include <type_traits >
3

4 void foo(char *);


5 void foo(int);
6

7 int main () {
8 if (std :: is_same < decltype (NULL), decltype (0) >:: value)
9 std :: cout << "NULL == 0" << std :: endl;
10 if (std :: is_same < decltype (NULL), decltype (( void *)0) >:: value)
11 std :: cout << "NULL == (void *)0" << std :: endl;
12 if (std :: is_same < decltype (NULL), std :: nullptr_t >:: value)
13 std :: cout << "NULL == nullptr " << std :: endl;
14

15 foo (0); // will call foo(int)


16 // foo(NULL); // doesn 't compile
17 foo( nullptr ); // will call foo(char *)
18 return 0;
19 }
20

21 void foo(char *) {
22 std :: cout << "foo(char *) is called " << std :: endl;
23 }
24 void foo(int i) {
25 std :: cout << "foo(int) is called " << std :: endl;
26 }

The outputs are:

1 foo(int) is called
2 foo(char *) is called

From the output we can see that NULL is different from 0 and nullptr. So, develop the habit of using
nullptr directly.

In addition, in the above code, we used decltype and std::is_same which are modern C++ syntax.

14
2.1 Constants CHAPTER 02: LANGUAGE USABILITY ENHANCEMENTS

In simple terms, decltype is used for type derivation, and std::is_same is used. To compare the equality
of the two types, we will discuss them in detail later in the decltype section.

constexpr

C++ itself already has the concept of constant expressions, such as 1+2, 3*4. Such expressions
always produce the same result without any side effects. If the compiler can directly optimize and embed
these expressions into the program at compile time, it will increase the performance of the program. A
very obvious example is in the definition phase of an array:

1 # include <iostream >


2 # define LEN 10
3

4 int len_foo () {
5 int i = 2;
6 return i;
7 }
8 constexpr int len_foo_constexpr () {
9 return 5;
10 }
11

12 constexpr int fibonacci ( const int n) {


13 return n == 1 || n == 2 ? 1 : fibonacci (n -1) + fibonacci (n -2);
14 }
15

16

17 int main () {
18 char arr_1 [10]; // legal
19 char arr_2 [LEN ]; // legal
20

21 int len = 10;


22 // char arr_3[len ]; // illegal
23

24 const int len_2 = len + 1;


25 constexpr int len_2_constexpr = 1 + 2 + 3;
26 // char arr_4[len_2 ]; // illegal , but ok for most of the
compilers
27 char arr_4 [ len_2_constexpr ]; // legal
28

29 // char arr_5[ len_foo () +5]; // illegal


30 char arr_6 [ len_foo_constexpr () + 1]; // legal
31

32 // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55


33 std :: cout << fibonacci (10) << std :: endl;
34

15

You might also like