diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
index a9d7187d..b7608bb6 100644
--- a/.github/workflows/website.yml
+++ b/.github/workflows/website.yml
@@ -9,21 +9,38 @@ jobs:
build:
name: Website
runs-on: ubuntu-latest
- timeout-minutes: 60
+ timeout-minutes: 20
steps:
- - uses: actions/checkout@v2
- - name: build
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+ cache: npm
+ cache-dependency-path: website/package-lock.json
+
+ # The Hexo site only needs Node and Python 3 (preinstalled on the
+ # runner). The old pipeline shelled out to a hand-maintained 3.4 GB
+ # texlive Docker image just to also build the PDF/epub; that image
+ # silently drifted to a 2019 Node and broke the build. We deploy the
+ # website only here. The PDF/epub already on the server are left in
+ # place (scp overwrites, never deletes), so their download links keep
+ # working until those artifacts are rebuilt separately.
+ - name: Install website dependencies
+ run: npm ci --prefix website
+
+ - name: Build website
+ run: cd website && make
+
+ - name: Deploy to server
env:
USER: ${{ secrets.SERVER_USER }}
TARGET: ${{ secrets.SERVER_PATH }}
KEY: ${{ secrets.SERVER_KEY }}
DOMAIN: ${{ secrets.SERVER_DOMAIN }}
run: |
- make build
- mkdir ~/.ssh
+ mkdir -p ~/.ssh
echo "$KEY" | tr -d '\r' > ~/.ssh/id_ed25519
chmod 400 ~/.ssh/id_ed25519
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_ed25519
- ssh-keyscan -H $DOMAIN >> ~/.ssh/known_hosts
- scp -r website/public/modern-cpp/* $USER@$DOMAIN:$TARGET
\ No newline at end of file
+ ssh-keyscan -H "$DOMAIN" >> ~/.ssh/known_hosts
+ scp -i ~/.ssh/id_ed25519 -r website/public/modern-cpp/* "$USER@$DOMAIN:$TARGET"
diff --git a/.gitignore b/.gitignore
index 1c18bcf2..9f221977 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,10 @@ website/src/modern-cpp/zh-cn/*
website/src/modern-cpp/en-us/*
website/src/modern-cpp/exercises
website/src/modern-cpp/code
+website/src/modern-cpp/assets/alipay.jpg
website/src/modern-cpp/assets/cover-2nd-en.png
website/src/modern-cpp/assets/cover-2nd.png
-website/src/modern-cpp/assets/figures/*
\ No newline at end of file
+website/src/modern-cpp/assets/cover-2nd-en-logo.png
+website/src/modern-cpp/assets/cover-2nd-logo.png
+website/src/modern-cpp/assets/figures/*
+website/src/modern-cpp/assets/wechat.jpg
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 054bc2ad..768f20a7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
## Submit Issue
-C++ 11/14/17 issue is used to track the principle description error, `typo` error, and the questions to the author of the book.
+The issue tracker for this book (covering C++11 to C++26) is used to track principle description errors, `typo` errors, and questions to the author of the book.
- Usually, you may encounter typos, semantic errors, grammatical errors, and etc. These are all `typo` errors. If an error has caused some obstacles to your reading and you strongly believe that the `typo` will also affect others reading, then you are very welcome to [submit issue](https://github.com/changkun/modern-cpp-tutorial/issues) to report the `typo` error.
@@ -15,15 +15,15 @@ Report the error immediately by [submitting issue](https://github.com/changkun/m
## Pull Request
-"C++ 11/14/17 On the Fly" is open source so that everyone can contribute to contribute via a PR. However, it is required to read the following instructions carefully before submitting your pull request:
+"Modern C++ Tutorial: C++11 to C++26 On the Fly" is open source so that everyone can contribute via a PR. Please read the following instructions carefully before submitting your pull request:
- Before you submit your pull request, make sure that the [issue list](https://github.com/changkun/modern-cpp-tutorial/issues) already contains the problem you want to solve. If not, please refer to the **Submit Issue** section.
-- Make sure your PR has improved more than 50 `typo` errors, otherwise please do not submit a PR.
+- Fixes of any size are welcome. For trivial `typo` fixes, please consider batching several of them into a single PR rather than opening many tiny PRs.
- For a PR that fixes principled errors, please don't hesitate, all of the readers of the book are very grateful for your contribution!
-- If you would like to be a co-author of this book, please send an email to ask: `hi at changkun dot us`.
+- If you would like to be a co-author of this book, please send an email to ask: `hi at changkun dot de`.
Since this repository provides a variety of reading approaches, thus make sure you have checked all items in the following checklist:
@@ -35,7 +35,7 @@ Since this repository provides a variety of reading approaches, thus make sure y
## 提交 Issue
-『C++ 11/14/17/20』的 issue 用于追踪书中存在的原则性的描述错误、存在的 `typo` 错误,以及向本书作者提问等。
+本书(覆盖 C++11 到 C++26)的 issue 用于追踪书中存在的原则性的描述错误、存在的 `typo` 错误,以及向本书作者提问等。
- 通常情况下,你可能会发现书中某个段落存在错别字、语义错误、文法错误等。
这都是 `typo` 错误。如果该错误已经对你的阅读造成了一定障碍,
@@ -51,18 +51,18 @@ Since this repository provides a variety of reading approaches, thus make sure y
- 如果你在阅读本书的时候发现有部分内容难于理解,也欢迎[提交 issue](https://github.com/changkun/modern-cpp-tutorial/issues) 来询问作者表达你的疑惑。
作者会根据实际情况重新优化这一部分的内容,进而帮助他人更易阅读这部分的内容。
-- 我们也欢迎你提交针对本书内容的相关建议,具体来说如果你认为书中未涉及的某个模块或者文件的源码值得讨论,也欢迎 [提交 issue](https://github.com/changkun/go-under-the-hood/issues) 来进一步讨论。
+- 我们也欢迎你提交针对本书内容的相关建议,具体来说如果你认为书中未涉及的某个模块或者文件的源码值得讨论,也欢迎 [提交 issue](https://github.com/changkun/modern-cpp-tutorial/issues) 来进一步讨论。
## 提交 Pull request
-『C++ 11/14/17/20』是一本开源书籍,任何人都可以参与贡献自己 PR。但在提交 PR 之前请仔细阅读下面的说明:
+『现代 C++ 教程:高速上手 C++11 到 C++26』是一本开源书籍,任何人都可以参与贡献自己 PR。但在提交 PR 之前请仔细阅读下面的说明:
- 当你认为需要提交一个 PR 时,请确保 [issue 列表](https://github.com/changkun/modern-cpp-tutorial/issues)中,已经包含了你想要解决的问题。
如果没有,请参考**提交 Issue** 一节中的描述,提交你的 issue,再提交你的 PR。
-- 当你准备提交一个 typo 错误的 PR 时,请确保你的 PR 改进了 **超过 50 个汉字(或英文单词)** 的 `typo` 错误,否则请不要提交 PR。
+- 任何大小的修正都欢迎。对于细小的 `typo` 修正,建议将多处一并合入到同一个 PR 中,而不是分散为许多零碎的 PR。
- 对于一个修复原则性错误的 PR,请不要犹豫,笔者对此表示非常感谢!
-- 如果非常喜欢本书,以至于希望参与本书的合著,成为作者,请发邮件询问:`hi at changkun dot us`。
+- 如果非常喜欢本书,以至于希望参与本书的合著,成为作者,请发邮件询问:`hi at changkun dot de`。
本仓库提供了多种阅读方式,如果你提交一个 Pull request,则请确保你检查的如下的 checklist:
diff --git a/README-zh-cn.md b/README-zh-cn.md
index 1b0aef83..70974d5d 100644
--- a/README-zh-cn.md
+++ b/README-zh-cn.md
@@ -1,12 +1,12 @@
-# 现代 C++ 教程:高速上手 C++11/14/17/20
+# 现代 C++ 教程:高速上手 C++11 到 C++26
- [](./README.md) [](./README-zh-cn.md) [](./assets/donate.md)
+[](https://github.com/changkun/modern-cpp-tutorial/actions/workflows/website.yml) [](./README.md) [](./README-zh-cn.md) [](./assets/donate.md)
## 本书目的
-本书号称『高速上手』,从内容上对二十一世纪二十年代之前产生 C++ 的相关特性做了非常相对全面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容。这些特性并不需要全部掌握,只需针对自己的使用需求和特定的应用场景,学习、查阅最适合自己的新特性即可。
+本书号称『高速上手』,从内容上对现代 C++(从 C++11 到 C++26)的相关特性做了相对全面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容。这些特性并不需要全部掌握,只需针对自己的使用需求和特定的应用场景,学习、查阅最适合自己的新特性即可。
同时,本书在介绍这些特性的过程中,尽可能简单明了的介绍了这些特性产生的历史背景和技术需求,这为理解这些特性、运用这些特性提供了很大的帮助。
@@ -50,15 +50,8 @@ $ make build
笔者时间和水平有限,如果读者发现书中内容的错误,欢迎提 [Issue](https://github.com/changkun/modern-cpp-tutorial/issues),或者直接提 [Pull request](https://github.com/changkun/modern-cpp-tutorial/pulls)。详细贡献指南请参考[如何参与贡献](CONTRIBUTING.md),由衷感谢每一位指出本书中出现错误的读者,包括但不限于 [Contributors](https://github.com/changkun/modern-cpp-tutorial/graphs/contributors)。
-
本项目还由以下产品提供赞助支持:
-
-
-
-
-
-
## 许可
-
+
-本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](./LICENSE)。
+本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](https://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](./LICENSE)。
diff --git a/README.md b/README.md
index 537b6adb..094044ac 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# Modern C++ Tutorial: C++11/14/17/20 On the Fly
+# Modern C++ Tutorial: C++11 to C++26 On the Fly
- [](./README.md) [](./README-zh-cn.md) [](./assets/donate.md)
+[](https://github.com/changkun/modern-cpp-tutorial/actions/workflows/website.yml) [](./README.md) [](./README-zh-cn.md) [](./assets/donate.md)
## Purpose
-The book claims to be "On the Fly". Its intent is to provide a comprehensive introduction to the relevant features regarding modern C++ (before 2020s).
+The book claims to be "On the Fly". Its intent is to provide a comprehensive introduction to the relevant features of modern C++ (from C++11 through C++26).
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 be aware that not all of these features are required. Instead, it should be learned when you really need it.
@@ -56,13 +56,6 @@ The author has limited time and language skills. If readers find any mistakes in
The author is grateful to all contributors, including but not limited to [Contributors](https://github.com/changkun/modern-cpp-tutorial/graphs/contributors).
-This project is also supported by:
-
-
-
-
-
-
## Licenses
-
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](./LICENSE).
+
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](./LICENSE).
diff --git a/book/en-us/00-preface.md b/book/en-us/00-preface.md
index 83835094..5fe564bb 100644
--- a/book/en-us/00-preface.md
+++ b/book/en-us/00-preface.md
@@ -10,14 +10,14 @@ order: 0
## Introduction
-C++ user group is 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 amazed by the fact that they are not using the same language while reading modern C++ code.
+The C++ programming language owns a fairly large user group. From the advent of C++98 to the official finalization of C++11, it has continued to stay relevant. 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 integrated into the C++ language and infuse it with new vitality.
+C++ programmers who are still using **traditional C++** (this book refers to C++98 and its previous standards as traditional C++) may even amazed 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 a 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, etc). It has become commonplace, and the emergence of rvalue references has solved the problem of temporary object efficiency that C++ has long been criticized for.
+**Modern C++** (this book refers to C++11 through C++26) introduces many features into traditional C++ which bring the entire language to a new level of modernization. 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 given C++ the "closure" feature of "anonymous functions", which are in almost all modern programming languages (such as Python, Swift, etc). It has become commonplace, and the emergence of rvalue references has solved the problem of temporary object efficiency that C++ has long been criticized for.
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 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 verify the compile-time of template parameters, further enhancing the usability of the language.
+Modern C++ also adds a lot of tools and methods to its 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 verify 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.
@@ -27,10 +27,22 @@ In conclusion, as an advocate and practitioner of C++, we always maintain an ope
- 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 to offer a quick start for modern C++. Of course, advanced readers can also use this book to review and examine themselves on modern C++.
+## How to read this book
+
+Modern C++ is large, and you do not need to read every page in order. This book assumes you are already comfortable with the basics of C++ — roughly the C++11-era language: classes, templates, and the common standard-library containers. If that describes you (for example, you learned some C++ at university), feel free to skim the parts you already know and focus on what is new to you.
+
+Several aids are built in to help you navigate:
+
+- Each feature is marked with the standard that introduced it (for example, *(since C++17)*), so you can tell at a glance what is newer than the C++ you already know.
+- [Appendix 3](./appendix3.md) is a feature index that maps each feature to the chapter where it appears and the standard it came from — handy for jumping straight to "what's new in C++20", or for looking a feature up later.
+- The book is organized in three parts: the **language core** (Chapters 1–3), the **standard library** (Chapters 4–9), and a **tour by standard version** (Chapters 10–12, covering C++20, C++23, and the forthcoming C++26).
+
+Rather than trying to memorize every feature, treat this book as a reference you return to: reach for a feature when a real problem calls for it.
+
## Purpose
-The book claims "On the Fly". It intends to provide a comprehensive introduction to the relevant features regarding modern C++ (before the 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.
+The book claims "On the Fly". It intends to provide a comprehensive introduction to the relevant features of modern C++, from C++11 all the way to C++26.
+Readers can choose interesting content according to the following table of contents to learn and quickly familiarize themselves with the new features that are available.
Readers should aware that all of these features are not required. It should be learned when you 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 come out.
@@ -39,14 +51,14 @@ Also, the author would like to encourage that readers should be able to use mode
## 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](../../code). All the code is organized by chapter, the folder name is the chapter number.
+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](https://github.com/changkun/modern-cpp-tutorial/tree/master/code). All the code is 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](../../exercise). The folder name is the chapter number.
+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](https://github.com/changkun/modern-cpp-tutorial/tree/master/exercises). The folder name is the chapter number.
[Table of Content](./toc.md) | [Next Chapter: Towards Modern C++](./01-intro.md)
## Licenses
-
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](../../LICENSE).
+
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](../../LICENSE).
diff --git a/book/en-us/01-intro.md b/book/en-us/01-intro.md
index e31087bb..03ecd88c 100644
--- a/book/en-us/01-intro.md
+++ b/book/en-us/01-intro.md
@@ -43,7 +43,7 @@ Before learning modern C++, let's take a look at the main features that have dep
- **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 ``, ``, `` and `` Wait**
+- **In particular, some of the C standard libraries that can be used are deprecated in the latest C++17 standard, such as ``, ``, `` and `` etc.**
- ... and many more
@@ -146,4 +146,4 @@ Don't worry at the moment, we will come to meet them in our later chapters.
## Licenses
-
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](../../LICENSE).
+
This work was written by [Ou Changkun](https://changkun.de) and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. The code of this repository is open sourced under the [MIT license](../../LICENSE).
diff --git a/book/en-us/02-usability.md b/book/en-us/02-usability.md
index 92f041fc..495f4bd7 100644
--- a/book/en-us/02-usability.md
+++ b/book/en-us/02-usability.md
@@ -18,20 +18,23 @@ which refers to the language behavior that occurred before the runtime.
### 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`.
+*(since C++11)*
-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:
+The purpose of `nullptr` appears to replace `NULL`. There are **null pointer constants** in the C and C++ languages,
+which can be implicitly converted to null pointer value of any pointer type,
+or null member pointer value of any pointer-to-member type in C++.
+`NULL` is provided by the standard library implementation and defined as an implementation-defined null pointer constant.
+In C, some standard libraries defines `NULL` as `((void*)0)` and some define it as `0`.
+
+C++ **does not allow** to implicitly convert `void *` to other types, and thus `((void*)0)` is not a valid implementation
+of `NULL`. If the standard library tries to define `NULL` as `((void*)0)`, then compilation error would occur in the following code:
```cpp
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.
+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:
```cpp
@@ -39,9 +42,9 @@ void foo(char*);
void foo(int);
```
-Then the `foo(NULL);` statement will call `foo(int)`, which will cause the code to be counterintuitive.
+Then the behavior of the `foo(NULL);` statement depends on how `NULL` is implemented: when `NULL` is defined as `0` (for example, on MSVC), it calls `foo(int)`, which is counterintuitive; when `NULL` is defined as the GCC/Clang builtin `__null`, the call `foo(NULL)` becomes ambiguous between the `char*` and `int` overloads and fails to compile. In either case, `NULL` does not behave the way a proper null pointer should during overload resolution.
-To solve this problem, C++11 introduced the `nullptr` keyword, which is specifically used to distinguish 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.
+To solve this problem, C++11 introduced the `nullptr` keyword, which is specifically used to distinguish 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++:
@@ -92,6 +95,8 @@ We will discuss them in detail later in the [decltype](#decltype) section.
### constexpr
+*(since C++11; relaxed in C++14)*
+
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
@@ -146,14 +151,12 @@ we need to use the `constexpr` feature introduced in C++11, which will be introd
to solve this problem; for `arr_5`, before C++98 The compiler cannot know that `len_foo()`
actually returns a constant at runtime, which causes illegal production.
-> Note that most compilers now have their compiler optimizations.
-> Many illegal behaviors become legal under the compiler's optimization.
-> If you need to reproduce the error, you need to use the old version of the compiler.
+> Note that some compilers (e.g. GCC, Clang) have compiler extensions enabled by default, supporting a C feature called "[variable-length arrays](https://en.cppreference.com/w/c/language/array#Variable-length_arrays)", which allows defining an array whose length is a non-constant expression and causes the above commented out illegal code to be compilable. To disable the extension, add the compilation option [`-pedantic-errors`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-pedantic-errors) (available for both GCC and Clang).
C++11 provides `constexpr` to let the user explicitly declare that the function or
object constructor will become a constant expression at compile time.
This keyword explicitly tells the compiler that it should verify that `len_foo`
-should be a compile-time constant expression. Constant expression.
+should be a compile-time constant expression.
In addition, the function of `constexpr` can use recursion:
@@ -189,6 +192,8 @@ constexpr int fibonacci(const int n) {
### if-switch
+*(since C++17)*
+
In traditional C++, the declaration of a variable can declare a temporary variable `int`
even though it can be located anywhere, even within a `for` statement,
but there is always no way to declare a temporary variable in the `if` and `switch` statements.
@@ -202,29 +207,32 @@ E.g:
int main() {
std::vector vec = {1, 2, 3, 4};
- // since c++17, can be simplified by using `auto`
+ // before C++17, can be simplified by using `auto`
const std::vector::iterator itr = std::find(vec.begin(), vec.end(), 2);
if (itr != vec.end()) {
*itr = 3;
}
- if (const std::vector::iterator itr = std::find(vec.begin(), vec.end(), 3);
- itr != vec.end()) {
- *itr = 4;
+ // need to define a new variable
+ const std::vector::iterator itr2 = std::find(vec.begin(), vec.end(), 3);
+ if (itr2 != vec.end()) {
+ *itr2 = 4;
}
- // should output: 1, 4, 3, 4. can be simplified using `auto`
- for (std::vector::iterator element = vec.begin(); element != vec.end(); ++element)
+ // will output: 1, 4, 3, 4; can be simplified using `auto`
+ for (std::vector::iterator element = vec.begin(); element != vec.end();
+ ++element)
std::cout << *element << std::endl;
}
```
In the above code, we can see that the `itr` variable is defined in the scope of
the entire `main()`, which causes us to rename the other when a variable need to traverse
-the entire `std::vectors` again. C++17 eliminates this limitation so that
+the entire `std::vector` again. C++17 eliminates this limitation so that
we can do this in if(or switch):
```cpp
+// put the temporary variable into the if-statement
if (const std::vector::iterator itr = std::find(vec.begin(), vec.end(), 3);
itr != vec.end()) {
*itr = 4;
@@ -235,6 +243,8 @@ Is it similar to the Go?
### Initializer list
+*(since C++11)*
+
Initialization is a very important language feature,
the most common one is when the object is initialized.
In traditional C++, different objects have different initialization methods,
@@ -285,6 +295,8 @@ such as:
```cpp
#include
#include
+#include
+
class MagicFoo {
public:
std::vector vec;
@@ -299,7 +311,9 @@ int main() {
MagicFoo magicFoo = {1, 2, 3, 4, 5};
std::cout << "magicFoo: ";
- for (std::vector::iterator it = magicFoo.vec.begin(); it != magicFoo.vec.end(); ++it) std::cout << *it << std::endl;
+ for (std::vector::iterator it = magicFoo.vec.begin();
+ it != magicFoo.vec.end(); ++it)
+ std::cout << *it << std::endl;
}
```
@@ -312,7 +326,8 @@ be used as a formal parameter of a normal function, for example:
```Cpp
public:
void foo(std::initializer_list list) {
- for (std::initializer_list::iterator it = list.begin(); it != list.end(); ++it) vec.push_back(*it);
+ for (std::initializer_list::iterator it = list.begin();
+ it != list.end(); ++it) vec.push_back(*it);
}
magicFoo.foo({6,7,8,9});
@@ -326,18 +341,11 @@ Foo foo2 {3, 4};
### Structured binding
-Structured bindings provide functionality similar to the multiple return values
-provided in other languages. In the chapter on containers,
-we will learn that C++11 has added a `std::tuple` container for
-constructing a tuple that encloses multiple return values. But the flaw
-is that C++11/14 does not provide a simple way to get and define
-the elements in the tuple from the tuple,
-although we can unpack the tuple using `std::tie`
-But we still have to be very clear about how many objects this tuple contains,
-what type of each object is, very troublesome.
+*(since C++17)*
+
+Functions frequently need to "return several values at once" — for example, a computed result together with a status flag. In traditional C++ this is not elegant: we either define a dedicated struct for it, or pack the values into a `std::tuple` and return that, but getting the values back out is clumsy — unpacking with `std::tie` forces us to declare every variable in advance and to know exactly how many elements the tuple holds and the type of each, and any mismatch is an error.
-C++17 completes this setting,
-and the structured bindings let us write code like this:
+C++17's **structured bindings** exist precisely to remove that clumsiness: they let us, in a single line, "unpack" a tuple, a `std::pair`, a raw array, or a struct with public data members, and bind the pieces directly to a set of named variables, with the types deduced by the compiler:
```cpp
#include
@@ -354,6 +362,19 @@ int main() {
}
```
+Compared with `std::tie`, structured bindings need no prior declaration and no spelled-out types, and they work not only on tuples but also on raw arrays and aggregate structs. This is especially handy when iterating an associative container: we can bind each key/value pair to meaningful names instead of writing `it->first` / `it->second`:
+
+```cpp
+#include
+#include