diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..2957eb0e --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [changkun] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 00000000..a9d7187d --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,29 @@ +name: Website + +on: + push: + branches: [ master ] + +jobs: + + build: + name: Website + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v2 + - name: build + env: + USER: ${{ secrets.SERVER_USER }} + TARGET: ${{ secrets.SERVER_PATH }} + KEY: ${{ secrets.SERVER_KEY }} + DOMAIN: ${{ secrets.SERVER_DOMAIN }} + run: | + make build + mkdir ~/.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 diff --git a/.gitignore b/.gitignore index e2365a98..f6224793 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,11 @@ 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/about/donate.md +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/qq-group.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/.travis.yml b/.travis.yml deleted file mode 100644 index ca4819ff..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -services: - - docker - -before_install: -- openssl aes-256-cbc -K $encrypted_9157553ce13c_key -iv $encrypted_9157553ce13c_iv -in .travis/travis.enc -out ~/.ssh/id_rsa -d -- chmod 600 ~/.ssh/id_rsa -- git config --global user.name "Changkun Ou" -- git config --global user.email "hi@changkun.us" - -addons: - ssh_known_hosts: - - changkun.de - -script: - - make build - -after_success: - scp -r website/public/modern-cpp/* $encrypted_server_user@changkun.de:$encrypted_server_path diff --git a/.travis/travis.enc b/.travis/travis.enc deleted file mode 100644 index 220056d8..00000000 Binary files a/.travis/travis.enc and /dev/null differ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5266cd9f..054bc2ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,32 +4,32 @@ C++ 11/14/17 issue is used to track the principle description error, `typo` error, and the 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. +- 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. -- Do not hasitate to submit a principle error because it prevent wrong knowledge being propagation. -Report the error immediately by [submitting issue](https://github.com/changkun/modern-cpp-tutorial/issues) to avoid the spread of wrong knowledge. +- Do not hesitate to submit a `principle` error because it will prevent wrong knowledge being spread. +Report the error immediately by [submitting issue](https://github.com/changkun/modern-cpp-tutorial/issues) to avoid the propogation of wrong knowledge. -- If you found some part of the book is confusing, you are very welcome to [submit an issue](https://github.com/changkun/modern-cpp-tutorial/issues) for asking questions. +- If you found some part of the book confusing, you are very welcome to [submit an issue](https://github.com/changkun/modern-cpp-tutorial/issues) for asking questions. -- The book cannot cover the entire C++ of course, however, you are very welcome to [submit an issue](https://github.com/changkun/modern-cpp-tutorial/issues) for a suggestion if you found some important feature is missing in the book. +- The book cannot cover the entirety C++ of course, however, you are very welcome to [submit an issue](https://github.com/changkun/modern-cpp-tutorial/issues) with a suggestion if you find some important feature is missing in the book. ## Pull Request -"C++ 11/14/17 On the Fly" is open source so that everyone can contribute to contribute to PR. However, it is required read the following instructions carefully before submitting your 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: - 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 the `typo` error of more than 50 words, otherwise please do not submit a PR. +- Make sure your PR has improved more than 50 `typo` errors, otherwise please do not submit a PR. -- For a PR that fixes principled errors, please don't hesitate, all readers of the book are very grateful for your contribution! +- 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`. Since this repository provides a variety of reading approaches, thus make sure you have checked all items in the following checklist: - [ ] If you only making changes to the main part of the book (i.e. the `book` folder), and no changes to the code snippet, then you are good to go; -- [ ] If you also change the code snippet in the main body of the book, then you need to synchronize the corresponding code snippet in the `code` folder; -- [ ] If you changes also involve the exercises, you also need to synchronize the contents of the `exercises` folder. +- [ ] If you also changed the code snippet in the main body of the book, then you need to synchronize the corresponding code snippet in the `code` folder; +- [ ] If your changes also involve the exercises, you also need to synchronize the contents of the `exercises` folder. # 如何参与贡献 diff --git a/LICENSE b/LICENSE index eaf37d56..3800ec13 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016 - 2019 Changkun Ou +Copyright (c) 2016 - 2020 Changkun Ou Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 6e5b53bd..f957a0de 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -DOCKER_ENV=changkun/modern-cpp-tutorial:build-env +NAME=modern-cpp-tutorial +DOCKER_ENV=changkun/$(NAME):build-env TARGET = pdf epub LANGS = zh-cn en-us ALL_BUILDS = website $(TARGET) @@ -11,14 +12,14 @@ $(TARGET): $(LANGS) mkdir -p website/public/modern-cpp/$@/ for lang in $^ ; do \ cd $@/$${lang} && make && make clean && cd ../..; \ - mv $@/$${lang}/modern-cpp-tutorial.$@ website/public/modern-cpp/$@/modern-cpp-tutorial-$${lang}.$@; \ + mv $@/$${lang}/$(NAME).$@ website/public/modern-cpp/$@/$(NAME)-$${lang}.$@; \ done website: cd website && make build: - docker run --rm -v `pwd`:/modern-cpp-tutorial -it $(DOCKER_ENV) make + docker run --rm -v `pwd`:/$(NAME) $(DOCKER_ENV) make # dev diff --git a/README-zh-cn.md b/README-zh-cn.md index ef897581..4b06afa7 100644 --- a/README-zh-cn.md +++ b/README-zh-cn.md @@ -2,7 +2,7 @@ # 现代 C++ 教程:高速上手 C++11/14/17/20 -![](https://img.shields.io/travis/changkun/modern-cpp-tutorial/master?style=flat-square) [![](https://img.shields.io/badge/language-English-blue.svg?style=flat-square)](./README.md) [![](https://img.shields.io/badge/language-简体中文-red.svg?style=flat-square)](./README-zh-cn.md) [![](https://img.shields.io/badge/€-donate-ff69b4.svg?style=flat-square)](./assets/donate.md) [![](https://img.shields.io/badge/chat-community-667ed5.svg?style=flat-square)](./assets/community.md) +![](https://img.shields.io/travis/changkun/modern-cpp-tutorial/master?style=flat-square) [![](https://img.shields.io/badge/language-English-blue.svg?style=flat-square)](./README.md) [![](https://img.shields.io/badge/language-简体中文-red.svg?style=flat-square)](./README-zh-cn.md) [![](https://img.shields.io/badge/€-donate-ff69b4.svg?style=flat-square)](./assets/donate.md) ## 本书目的 @@ -22,7 +22,7 @@ 你可以选择以下几种阅读方式: 1. [GitHub 在线](./book/zh-cn/toc.md) -2. [PDF 文档](https://changkun.de/modern-cpp/modern-cpp-tutorial-zh-cn.pdf) +2. [PDF 文档](https://changkun.de/modern-cpp/pdf/modern-cpp-tutorial-zh-cn.pdf) 3. [EPUB 文档](https://changkun.de/modern-cpp/epub/modern-cpp-tutorial-zh-cn.epub) 4. [网站](https://changkun.de/modern-cpp/) @@ -50,8 +50,15 @@ $ 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 5249e676..45df2bec 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,22 @@ # Modern C++ Tutorial: C++11/14/17/20 On the Fly -![](https://img.shields.io/travis/changkun/modern-cpp-tutorial/master?style=flat-square) [![](https://img.shields.io/badge/language-English-blue.svg?style=flat-square)](./README.md) [![](https://img.shields.io/badge/language-简体中文-red.svg?style=flat-square)](./README-zh-cn.md) [![](https://img.shields.io/badge/€-donate-ff69b4.svg?style=flat-square)](./assets/donate.md) [![](https://img.shields.io/badge/chat-community-667ed5.svg?style=flat-square)](./assets/community.md) - +![](https://img.shields.io/travis/changkun/modern-cpp-tutorial/master?style=flat-square) [![](https://img.shields.io/badge/language-English-blue.svg?style=flat-square)](./README.md) [![](https://img.shields.io/badge/language-简体中文-red.svg?style=flat-square)](./README-zh-cn.md) [![](https://img.shields.io/badge/€-donate-ff69b4.svg?style=flat-square)](./assets/donate.md) ## Purpose -The book claims "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 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. +Readers should be aware that not all of these features are required. Instead, it should be learned 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. +At the same time, instead of coding-only, the book introduces the historical background of its technical requirements (as simple as possible), which provides great help in understanding why these features came 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. +In addition, the author would like to encourage readers to use modern C++ directly in their new projects and migrate their old projects to modern C++ gradually after reading the book. ## 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 of modern C++ in a short period of time are well suited to read the book; +- This book assumes that readers are already familiar with traditional C++ (i.e. C++98 or earlier), or at least that 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 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++. +- This book introduces, to a certain extent, the dark magic of modern C++. However, these magic tricks 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++. ## Start @@ -31,19 +30,19 @@ You can choose from the following reading methods: ## 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 organized by chapter, the folder name is the chapter number. +Each chapter of this book contains a lot of code. If you encounter problems while writing your own code with the introductory features of the book, reading the source code attached to the book might be of help. You can find the book [here](./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](./exercises). The folder name is the chapter number. +There are few exercises at the end of each chapter of the book. These are meant to test whether you have mastered the knowledge in the current chapter. You can find the possible answer to the problem [here](./exercises). Again, the folder name is the chapter number. ## Website -The source code of the [website](https://changkun.de/modern-cpp) of this book can be found [here](./website), which is built by [hexo](https://hexo.io) and [vuejs](https://vuejs.org). The website provides you another way of reading the book, it is also adapts to mobile. +The source code of the [website](https://changkun.de/modern-cpp) of this book can be found [here](./website), which is built by [hexo](https://hexo.io) and [vuejs](https://vuejs.org). The website provides you another way of reading the book, it also adapts to mobile browsers. ## Build -If you are interested in build everything locally, it is recommended using [Docker](https://docs.docker.com/install/). To build, simply run: +If you are interested in building everything locally, it is recommended using [Docker](https://docs.docker.com/install/). To build, simply run: ```bash $ make build @@ -53,10 +52,17 @@ $ make build This book was originally written in Chinese by [Changkun Ou](https://changkun.de). -The author has limited time and language skills. If readers find any mistakes of the book or any language improvements, please feel free to open an [Issue](https://github.com/changkun/modern-cpp-tutorial/issues) or start a [Pull request](https://github.com/changkun/modern-cpp-tutorial/pulls). For detailed guidelines and checklist, please refer to [How to contribute](CONTRIBUTING.md). +The author has limited time and language skills. If readers find any mistakes in the book or any language improvements, please feel free to open an [Issue](https://github.com/changkun/modern-cpp-tutorial/issues) or start a [Pull request](https://github.com/changkun/modern-cpp-tutorial/pulls). For detailed guidelines and checklist, please refer to [How to contribute](CONTRIBUTING.md). + +The author is grateful to all contributors, including but not limited to [Contributors](https://github.com/changkun/modern-cpp-tutorial/graphs/contributors). -The author would be 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 -Creative Commons 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). \ No newline at end of file +Creative Commons 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/assets/community.md b/assets/community.md deleted file mode 100644 index 87b7333d..00000000 --- a/assets/community.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 社区 -type: about -order: 2 ---- - -## Community - -The book offers a telegram chat group, feel free to join if you are interested: - -[![](https://img.shields.io/badge/chat-telegram-blue.svg?style=popout-square&logo=telegram)](https://t.me/joinchat/FEeulBM5OVYzuDI4phQ9Mg) - -## 交流 - -本书有以下读者 QQ 交流群,有兴趣的读者可以加入,加群需正确回答加群密码: - -![](../assets/qq-group.png) - -> 提示: `bW9kZXJuLWNwcC10dXRvcmlhbC1naXRodWI=` - -本书还提供以下读者微信交流群,有兴趣的读者可以加入,加群请扫描如下二维码: - -![](../assets/wechat-group.jpg) - -若群已加满,请联系并添加 `oulongqi` 并注明『现代 C++ 教程』获取入群邀请。 diff --git a/assets/cover-2nd-en-logo.png b/assets/cover-2nd-en-logo.png new file mode 100644 index 00000000..050a18e0 Binary files /dev/null and b/assets/cover-2nd-en-logo.png differ diff --git a/assets/cover-2nd-logo.png b/assets/cover-2nd-logo.png new file mode 100644 index 00000000..a05a42a1 Binary files /dev/null and b/assets/cover-2nd-logo.png differ diff --git a/assets/figures/pointers1_en.png b/assets/figures/pointers1_en.png new file mode 100644 index 00000000..6a96338f Binary files /dev/null and b/assets/figures/pointers1_en.png differ diff --git a/assets/qq-group.png b/assets/qq-group.png deleted file mode 100644 index c567cd76..00000000 Binary files a/assets/qq-group.png and /dev/null differ diff --git a/assets/wechat-group.jpg b/assets/wechat-group.jpg deleted file mode 100644 index 29fdc7f1..00000000 Binary files a/assets/wechat-group.jpg and /dev/null differ diff --git a/book/en-us/00-preface.md b/book/en-us/00-preface.md index 3d3f7f69..b93705a3 100644 --- a/book/en-us/00-preface.md +++ b/book/en-us/00-preface.md @@ -10,36 +10,36 @@ order: 0 ## 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. +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 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. +**Modern C++** (this book refers to C++11/14/17/20) 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 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. +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. ## 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 of modern C++ in a short period of time are well suited to read the book; +- 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 of modern C++ in a short period 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++. +- 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++. ## 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. +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 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 comes out. +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. -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. +Also, 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 reading 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](../../code). All the code 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](../../code). All the code is organized by chapter, the folder name is the chapter number. ## Exercises @@ -49,4 +49,4 @@ There are few exercises At the end of each chapter of the book. It is for testin ## Licenses -Creative Commons 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). \ No newline at end of file +Creative Commons 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 96619c5b..03ecd88c 100644 --- a/book/en-us/01-intro.md +++ b/book/en-us/01-intro.md @@ -8,7 +8,7 @@ order: 1 [TOC] -**Compilation Environment**: This book will use `clang++` as the only compiler used, +**Compilation Environment**: This book will use `clang++` as the only compiler used, and always use the `-std=c++2a` compilation flag in your code. ```bash @@ -21,14 +21,15 @@ 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: +Before learning modern C++, let's take a look at the main features that have 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. +> **Note**: Deprecation is not completely unusable, it is only intended to imply that features will disappear from future standards and should be avoided. But, 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 - ``` + + ```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`.** @@ -42,19 +43,19 @@ Before learning modern C++, let's take a look at the main features that have bee - **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 -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. +There are also other features such as parameter binding (C++11 provides `std::bind` and `std::function`), `export` 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. ## 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. +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 Venn diagram in Figure 1.2 roughly answers the C and C++ related compatibility. ![Figure 1.2: Compatabilities between ISO C and ISO C++](../../assets/figures/comparison.png) -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: +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-readings) 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: ```cpp // foo.h @@ -92,7 +93,7 @@ You should first compile the C code with `gcc`: 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): +Compile and output the `foo.o` file, and link the C++ code to the `.o` file using `clang++` (or both compile to `.o` and then link them together): ```bash clang++ 1.1.cpp foo.o -std=c++2a -o 1.1 @@ -115,11 +116,12 @@ LDFLAGS_COMMON = -std=c++2a all: $(C) -c $(SOURCE_C) $(CXX) $(SOURCE_CXX) $(OBJECTS_C) $(LDFLAGS_COMMON) -o $(TARGET) + clean: rm -rf *.o $(TARGET) ``` -> Note: Indentation in `Makefile` is a tab instead of a space character. If you copy this code directly into your editor, the tab may be automatically replaced. Please ensure the indentation in the `Makefile`. It is done by tabs. +> **Note**: Indentation in `Makefile` is a tab instead of a space character. If you copy this code directly into your editor, the tab may be automatically replaced. Please ensure the indentation in the `Makefile` 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. @@ -144,4 +146,4 @@ Don't worry at the moment, we will come to meet them in our later chapters. ## Licenses -Creative Commons 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). \ No newline at end of file +Creative Commons 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 95df99c9..eb8a21aa 100644 --- a/book/en-us/02-usability.md +++ b/book/en-us/02-usability.md @@ -8,30 +8,31 @@ order: 2 [TOC] -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**, +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`. +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. -But if the compiler tries to define `NULL` as `((void*)0)`, then in the following code: +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 @@ -41,7 +42,7 @@ 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 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++: @@ -81,24 +82,22 @@ foo(int) is called foo(char*) is called ``` -From the output we can see that `NULL` is different from `0` and `nullptr`. +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. -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](#decltype) section. +In addition, in the above code, we used `decltype` and +`std::is_same` which are modern C++ syntax. +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](#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: +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: ```cpp #include @@ -131,7 +130,7 @@ int main() { // char arr_5[len_foo()+5]; // illegal char arr_6[len_foo_constexpr() + 1]; // legal - + // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 std::cout << fibonacci(10) << std::endl; @@ -139,23 +138,23 @@ int main() { } ``` -In the above example, `char arr_4[len_2]` may be confusing because `len_2` has been defined as a constant. -Why is `char arr_4[len_2]` still illegal? -This is because the length of the array in the C++ standard must be a constant expression, -and for `len_2`, this is a `const` constant, not a constant expression, -so even if this behavior is in most compilers Both support, but) it is an illegal behavior, -we need to use the `constexpr` feature introduced in C++11, which will be introduced next, -to solve this problem; for `arr_5`, before C++98 The compiler cannot know that `len_foo()` +In the above example, `char arr_4[len_2]` may be confusing because `len_2` has been defined as a constant. +Why is `char arr_4[len_2]` still illegal? +This is because the length of the array in the C++ standard must be a constant expression, +and for `len_2`, this is a `const` constant, not a constant expression, +so even if this behavior is supported by most compilers, but it is an illegal behavior, +we need to use the `constexpr` feature introduced in C++11, which will be introduced next, +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 own compiler optimizations. -> Many illegal behaviors become legal under the compiler's optimization. +> 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. -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. +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. In addition, the function of `constexpr` can use recursion: @@ -165,9 +164,9 @@ constexpr int fibonacci(const int n) { } ``` -Starting with C++14, -the constexpr function can use simple statements such as local variables, -loops, and branches internally. +Starting with C++14, +the constexpr function can use simple statements such as local variables, +loops, and branches internally. For example, the following code cannot be compiled under the C++11 standard: ```cpp @@ -178,7 +177,7 @@ constexpr int fibonacci(const int n) { } ``` -To do this, we can write a simplified version like this +To do this, we can write a simplified version like this to make the function available from C++11: ```cpp @@ -191,9 +190,9 @@ constexpr int fibonacci(const int n) { ### if-switch -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. +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. E.g: ```cpp @@ -204,7 +203,7 @@ E.g: int main() { std::vector vec = {1, 2, 3, 4}; - // after c++17, can be simplefied by using `auto` + // since 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; @@ -215,15 +214,16 @@ int main() { *itr = 4; } - // should output: 1, 4, 3, 4. can be simplefied using `auto` - for (std::vector::iterator element = vec.begin(); element != vec.end(); ++element) + // should 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 we need to traverse -the entire `std::vectors` again. A variable. C++17 eliminates this limitation so that +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::vector` again. C++17 eliminates this limitation so that we can do this in if(or switch): ```cpp @@ -237,17 +237,17 @@ Is it similar to the Go? ### Initializer list -Initialization is a very important language feature, -the most common one is when the object is initialized. +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, -such as ordinary arrays, PODs (**P**lain **O**ld **D**ata, -ie classes without constructs, destructors, and virtual functions) -Or struct type can be initialized with `{}`, -which is what we call the initialization list. -For the initialization of the class object, -you need to use the copy construct, -or you need to use `()`. -These different methods are specific to each other and cannot be generic. +such as ordinary arrays, PODs (**P**lain **O**ld **D**ata, +i.e. classes without constructs, destructors, and virtual functions) +Or struct type can be initialized with `{}`, +which is what we call the initialization list. +For the initialization of the class object, +you need to use the copy construct, +or you need to use `()`. +These different methods are specific to each other and cannot be generic. E.g: ```cpp @@ -276,22 +276,24 @@ int main() { } ``` -To solve this problem, -C++11 first binds the concept of the initialization list to the type -and calls it `std::initializer_list`, -allowing the constructor or other function to use the initialization list -like a parameter, which is The initialization of class objects provides -a unified bridge between normal arrays and POD initialization methods, +To solve this problem, +C++11 first binds the concept of the initialization list to the type +and calls it `std::initializer_list`, +allowing the constructor or other function to use the initialization list +like a parameter, which is the initialization of class objects provides +a unified bridge between normal arrays and POD initialization methods, such as: ```cpp #include #include +#include + class MagicFoo { public: std::vector vec; MagicFoo(std::initializer_list list) { - for (std::initializer_list::iterator it = list.begin(); + for (std::initializer_list::iterator it = list.begin(); it != list.end(); ++it) vec.push_back(*it); } @@ -301,20 +303,23 @@ 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; } ``` -This constructor is called the initialize list constructor, and the type with +This constructor is called the initialize list constructor, and the type with this constructor will be specially taken care of during initialization. -In addition to the object construction, the initialization list can also +In addition to the object construction, the initialization list can also be used as a formal parameter of a normal function, for example: ```Cpp -public: +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}); @@ -328,17 +333,17 @@ 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 directly 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, +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. -C++17 completes this setting, +C++17 completes this setting, and the structured bindings let us write code like this: ```cpp @@ -356,12 +361,12 @@ int main() { } ``` -The `auto` type derivation is described in the +The `auto` type derivation is described in the [auto type inference](#auto) section. ## 2.3 Type inference -In traditional C and C++, the types of parameters must be clearly defined, which does not help us to quickly encode, especially when we are faced with a large number of complex template types, we must clearly indicate the type of variables in order to proceed. Subsequent coding, which not only slows down our development efficiency, but also makes the code stinking and long. +In traditional C and C++, the types of parameters must be clearly defined, which does not help us to quickly encode, especially when we are faced with a large number of complex template types, we must indicate the type of variables to proceed. Subsequent coding, which not only slows down our development efficiency but also makes the code stinking and long. C++11 introduces the two keywords `auto` and `decltype` to implement type derivation, letting the compiler worry about the type of the variable. This makes C++ the same as other modern programming languages, in a way that provides the habit of not having to worry about variable types. @@ -374,8 +379,8 @@ One of the most common and notable examples of type derivation using `auto` is t ```cpp // before C++11 // cbegin() returns vector::const_iterator -// and therefore itr is type vector::const_iterator -for(vector::const_iterator it = vec.cbegin(); itr != vec.cend(); ++it) +// and therefore it is type vector::const_iterator +for(vector::const_iterator it = vec.cbegin(); it != vec.cend(); ++it) ``` When we have `auto`: @@ -413,31 +418,38 @@ auto i = 5; // i as int auto arr = new auto(10); // arr as int * ``` -> **Note**: `auto` cannot be used for function arguments, so the following -> is not possible to compile (considering overloading, -> we should use templates): -> ```cpp -> int add(auto x, auto y); -> -> 2.6.auto.cpp:16:9: error: 'auto' not allowed in function prototype -> int add(auto x, auto y) { -> ^~~~ -> ``` +Since C++ 14, `auto` can even be used as function arguments in generic lambda expressions, +and such functionality is generalized to normal functions in C++ 20. +Consider the following example: + +```cpp +auto add14 = [](auto x, auto y) -> int { + return x+y; +} + +int add20(auto x, auto y) { + return x+y; +} + +auto i = 5; // type int +auto j = 6; // type int +std::cout << add14(i, j) << std::endl; +std::cout << add20(i, j) << std::endl; +``` + +> **Note**: `auto` cannot be used to derive array types yet: > -> In addition, `auto` cannot be used to derive array types: -> > ```cpp -> auto auto_arr2[10] = arr; // illegal, can't infer array type +> auto auto_arr2[10] = {arr}; // illegal, can't infer array type > > 2.6.auto.cpp:30:19: error: 'auto_arr2' declared as array of 'auto' -> auto auto_arr2[10] = arr; +> auto auto_arr2[10] = {arr}; > ``` ### decltype -The `decltype` keyword is used to solve the defect that the auto keyword -can only type the variable. Its usage is very similar to `sizeof`: - +The `decltype` keyword is used to solve the defect that the auto keyword +can only type the variable. Its usage is very similar to `typeof`: ```cpp decltype(expression) @@ -451,9 +463,9 @@ auto y = 2; decltype(x+y) z; ``` -You have seen in the previous example that -`decltype` is used to infer the usage of the type. -The following example is to determine +You have seen in the previous example that +`decltype` is used to infer the usage of the type. +The following example is to determine if the above variables `x, y, z` are of the same type: ```cpp @@ -465,7 +477,7 @@ if (std::is_same::value) std::cout << "type z == type x" << std::endl; ``` -Among them, `std::is_same` is used to determine whether +Among them, `std::is_same` is used to determine whether the two types `T` and `U` are equal. The output is: ``` @@ -475,34 +487,34 @@ type z == type x ### tail type inference -You may think that when we introduce `auto`, we have already mentioned that `auto` cannot be used for function arguments for type derivation. Can `auto` be used to derive the return type of a function? Still consider an example of an add function, which we have to write in traditional C++: +You may think that whether `auto` can be used to deduce the return type of a function. Still consider an example of an add function, which we have to write in traditional C++: ```cpp template R add(T x, U y) { - return x+y + return x+y; } ``` -> Note: There is no difference between typename and class in the template parameter list. Before the keyword typename appears, class is used to define the template parameters. However, when defining a variable with [nested dependency type](http://en.cppreference.com/w/cpp/language/dependent_name#The_typename_disambiguator_for_dependent_names) in the template, you need to use typename to eliminate ambiguity. +> Note: There is no difference between typename and class in the template parameter list. Before the keyword typename appears, class is used to define the template parameters. However, when defining a variable with [nested dependency type](https://en.cppreference.com/w/cpp/language/dependent_name#The_typename_disambiguator_for_dependent_names) in the template, you need to use typename to eliminate ambiguity. -Such code is actually very ugly, because the programmer must explicitly -indicate the return type when using this template function. -But in fact we don't know what kind of operation +Such code is very ugly because the programmer must explicitly +indicate the return type when using this template function. +But in fact, we don't know what kind of operation the `add()` function will do, and what kind of return type to get. -This problem was solved in C++11. Although you may immediately -react to using `decltype` to derive the type of `x+y`, +This problem was solved in C++11. Although you may immediately +react to using `decltype` to derive the type of `x+y`, write something like this: ```cpp decltype(x+y) add(T x, U y) ``` -But in fact, this way of writing can not be compiled. -This is because `x` and `y` have not been defined -when the compiler reads decltype(x+y). -To solve this problem, C++11 also introduces a trailing return type, +But in fact, this way of writing can not be compiled. +This is because `x` and `y` have not been defined +when the compiler reads decltype(x+y). +To solve this problem, C++11 also introduces a trailing return type, which uses the auto keyword to post the return type: ```cpp @@ -512,7 +524,7 @@ auto add2(T x, U y) -> decltype(x+y){ } ``` -The good news is that from C++14 it is possible to directly derive the return value of +The good news is that from C++14 it is possible to directly derive the return value of a normal function, so the following way becomes legal: ```cpp @@ -541,16 +553,16 @@ std::cout << "q: " << q << std::endl; `decltype(auto)` is a slightly more complicated use of C++14. -> To understand it you need to know the concept of parameter forwarding -> in C++, which we will cover in detail in the -> [Language Runtime Hardening](./03-runtime.md) chapter, +> To understand it you need to know the concept of parameter forwarding +> in C++, which we will cover in detail in the +> [Language Runtime Enhancements](./03-runtime.md) chapter, > and you can come back to the contents of this section later. -In simple terms, `decltype(auto)` is mainly used to derive -the return type of a forwarding function or package, -which does not require us to explicitly specify -the parameter expression of `decltype`. -Consider the following example, when we need to wrap the following +In simple terms, `decltype(auto)` is mainly used to derive +the return type of a forwarding function or package, +which does not require us to explicitly specify +the parameter expression of `decltype`. +Consider the following example, when we need to wrap the following two functions: ```cpp @@ -584,7 +596,7 @@ decltype(auto) look_up_a_string_2() { ### if constexpr -As we saw at the beginning of this chapter, we know that C++11 introduces the `constexpr` keyword, which compiles expressions or functions into constant results. A natural idea is that if we introduce this feature into the conditional judgment, let the code complete the branch judgment at compile time, can it make the program more efficient? C++17 introduces the `constexpr` keyword into the `if` statement, allowing you to declare the condition of a constant expression in your code. Consider the following code: +As we saw at the beginning of this chapter, we know that C++11 introduces the `constexpr` keyword, which compiles expressions or functions into constant results. A natural idea is that if we introduce this feature into the conditional judgment, let the code complete the branch judgment at compile-time, can it make the program more efficient? C++17 introduces the `constexpr` keyword into the `if` statement, allowing you to declare the condition of a constant expression in your code. Consider the following code: ```cpp #include @@ -620,7 +632,7 @@ int main() { ### Range-based for loop -Finally, C++11 introduces a range-based iterative method, and we have the ability to write loops that are as concise +Finally, C++11 introduces a range-based iterative method, and we can write loops that are as concise as Python, and we can further simplify the previous example: ```cpp @@ -643,7 +655,7 @@ int main() { ## 2.5 Templates -C++ templates have always been a special art of the language, and templates can even be used independently as a new language. The philosophy of the template is to throw all the problems that can be processed at compile time into the compile time, and only deal with those core dynamic services at runtime, so as to greatly optimize the performance of the runtime. Therefore, templates are also regarded by many as one of the black magic of C++. +C++ templates have always been a special art of the language, and templates can even be used independently as a new language. The philosophy of the template is to throw all the problems that can be processed at compile time into the compile time, and only deal with those core dynamic services at runtime, to greatly optimize the performance of the runtime. Therefore, templates are also regarded by many as one of the black magic of C++. ### Extern templates @@ -664,9 +676,9 @@ In the traditional C++ compiler, `>>` is always treated as a right shift operato std::vector> matrix; ``` -This is not compiled under the traditional C++ compiler, -and C++11 starts with continuous right angle brackets that become legal -and can be compiled successfully. +This is not compiled under the traditional C++ compiler, +and C++11 starts with continuous right angle brackets that become legal +and can be compiled successfully. Even the following writing can be compiled by: ```cpp @@ -698,7 +710,7 @@ typedef MagicType, std::string> FakeDarkMagic; C++11 uses `using` to introduce the following form of writing, and at the same time supports the same effect as the traditional `typedef`: -> Usually we use `typedef` to define the alias syntax: `typedef original name new name; `, but the definition syntax for aliases such as function pointers is different, which usually causes a certain degree of difficulty for direct reading. +> Usually, we use `typedef` to define the alias syntax: `typedef original name new name; `, but the definition syntax for aliases such as function pointers is different, which usually causes a certain degree of difficulty for direct reading. ```cpp typedef int (*process)(void *); @@ -711,43 +723,21 @@ int main() { } ``` -### Default template parameters - -We may have defined an addition function: - -```cpp -template -auto add(T x, U y) -> decltype(x+y) { - return x+y; -} -``` - -However, when used, it is found that to use add, you must specify the type of its template parameters each time. - -A convenience is provided in C++11 to specify the default parameters of the template: - -```cpp -template -auto add(T x, U y) -> decltype(x+y) { - return x+y; -} -``` - ### Variadic templates -The template has always been one of C++'s unique **Black Magic**. -In traditional C++, -both a class template and a function template could only accept -a fixed set of template parameters as specified; -C++11 added a new representation, allowing any number, -template parameters of any category, +The template has always been one of C++'s unique **Black Magic**. +In traditional C++, +both a class template and a function template could only accept +a fixed set of template parameters as specified; +C++11 added a new representation, allowing any number, +template parameters of any category, and there is no need to fix the number of parameters when defining. ```cpp template class Magic; ``` -The template class Magic object can accept unrestricted number of typename as +The template class Magic object can accept an unrestricted number of typename as a formal parameter of the template, such as the following definition: ```cpp @@ -765,14 +755,14 @@ If you do not want to generate 0 template parameters, you can manually define at template class Magic; ``` -The variable length parameter template can also be directly adjusted to the template function. +The variable length parameter template can also be directly adjusted to the template function. The `printf` function in the traditional C, although it can also reach the call of an indefinite number of formal parameters, is not class safe. In addition to the variable-length parameter functions that define class safety, C++11 can also make printf-like functions naturally handle objects that are not self-contained. In addition to the use of `...` in the template parameters to indicate the indefinite length of the template parameters, the function parameters also use the same representation to represent the indefinite length parameters, which provides a convenient means for us to simply write variable length parameter functions, such as: ```cpp template void printf(const std::string &str, Args... args); ``` -Then we define variable length template parameters, +Then we define variable length template parameters, how to unpack the parameters? First, we can use `sizeof...` to calculate the number of arguments: @@ -793,14 +783,13 @@ magic(1); // 1 magic(1, ""); // 2 ``` -Second, the parameters are unpacked. So far there is no simple way to process +Second, the parameters are unpacked. So far there is no simple way to process the parameter package, but there are two classic processing methods: **1. Recursive template function** Recursion is a very easy way to think of and the most classic approach. This method continually recursively passes template parameters to the function, thereby achieving the purpose of recursively traversing all template parameters: - ```cpp #include template @@ -834,7 +823,7 @@ void printf2(T0 t0, T... t) { **3. Initialize list expansion** -Recursive template functions are a standard practice, but the obvious drawback is that you must define a function that terminates recursion. +Recursive template functions are standard practice, but the obvious drawback is that you must define a function that terminates recursion. Here is a description of the black magic that is expanded using the initialization list: @@ -874,14 +863,14 @@ What we mainly mentioned above is a form of template parameters: type template p ```cpp template - auto add(T t, U u) { +auto add(T t, U u) { return t+u; } ``` The parameters of the template `T` and `U` are specific types. -But there is also a common form of template parameter that allows different literals -to be template parameters, ie non-type template parameters: +But there is also a common form of template parameter that allows different literals +to be template parameters, i.e. non-type template parameters: ```cpp template @@ -897,7 +886,7 @@ buffer_t buf; // 100 as template parameter ``` In this form of template parameters, we can pass `100` as a parameter to the template. -After C++11 introduced the feature of type derivation, we will naturally ask, since the template parameters here +After C++11 introduced the feature of type derivation, we will naturally ask, since the template parameters here. Passing with a specific literal, can the compiler assist us in type derivation, By using the placeholder `auto`, there is no longer a need to explicitly specify the type? Fortunately, C++17 introduces this feature, and we can indeed use the `auto` keyword to let the compiler assist in the completion of specific types of derivation. @@ -918,7 +907,7 @@ int main() { ### Delegate constructor -C++11 introduces the concept of a delegate construct, which allows a constructor to call another constructor +C++11 introduces the concept of a delegate construct, which allows a constructor to call another constructor in a constructor in the same class, thus simplifying the code: ```cpp @@ -961,7 +950,7 @@ public: }; class Subclass : public Base { public: - using Base::Base; // inhereit constructor + using Base::Base; // inheritance constructor }; int main() { Subclass s(3); @@ -989,7 +978,7 @@ C++11 introduces the two keywords `override` and `final` to prevent this from ha ### override -When overriding a virtual function, introducing the `override` keyword will explicitly tell the compiler to overload, and the compiler will check if the base function has such a virtual function, otherwise it will not compile: +When overriding a virtual function, introducing the `override` keyword will explicitly tell the compiler to overload, and the compiler will check if the base function has such a virtual function with consistent function signature, otherwise it will not compile: ```cpp struct Base { @@ -1003,7 +992,7 @@ struct SubClass: Base { ### final -`final` is to prevent the class from being continued to inherit and to terminate +`final` is to prevent the class from being continued to inherit and to terminate the virtual function to continue to be overloaded. ```cpp @@ -1023,7 +1012,7 @@ struct SubClass3: Base { ### Explicit delete default function -In traditional C++, if the programmer does not provide it, the compiler will default to generating default constructors, copy constructs, assignment operators, and destructors for the object. In addition, C++ also defines operators such as `new` `delete` for all classes. This part of the function can be overridden when the programmer needs it. +In traditional C++, if the programmer does not provide it, the compiler will default to generating default constructors, copy constructs, assignment operators, and destructors for the object. Besides, C++ also defines operators such as `new` `delete` for all classes. This part of the function can be overridden when the programmer needs it. This raises some requirements: the ability to accurately control the generation of default functions cannot be controlled. For example, when copying a class is prohibited, the copy constructor and the assignment operator must be declared as `private`. Trying to use these undefined functions will result in compilation or link errors, which is a very unconventional way. @@ -1042,7 +1031,7 @@ class Magic { ### Strongly typed enumerations -In traditional C++, enumerated types are not type-safe, and enumerated types are treated as integers, which allows two completely different enumerated types to be directly compared (although the compiler gives the check, but not all) , ** Even the enumeration value names of different enum types in the same namespace cannot be the same**, which is usually not what we want to see. +In traditional C++, enumerated types are not type-safe, and enumerated types are treated as integers, which allows two completely different enumerated types to be directly compared (although the compiler gives the check, but not all), ** Even the enumeration value names of different enum types in the same namespace cannot be the same**, which is usually not what we want to see. C++11 introduces an enumeration class and declares it using the syntax of `enum class`: @@ -1070,7 +1059,9 @@ And we want to get the value of the enumeration value, we will have to explicitl ```cpp #include template -std::ostream& operator<<(typename std::enable_if::value, std::ostream>::type& stream, const T& e) +std::ostream& operator<<( + typename std::enable_if::value, + std::ostream>::type& stream, const T& e) { return stream << static_cast::type>(e); } @@ -1086,7 +1077,7 @@ std::cout << new_enum::value3 << std::endl This section introduces the enhancements to language usability in modern C++, which I believe are the most important features that almost everyone needs to know and use: -1. auto type derivation +1. Auto type derivation 2. Scope for iteration 3. Initialization list 4. Variable parameter template @@ -1099,7 +1090,7 @@ This section introduces the enhancements to language usability in modern C++, wh #include #include