├── Readme.txt ├── github_code ├── .github │ ├── ISSUE_TEMPLATE │ │ ├── Bug_report.md │ │ ├── Feature_request.md │ │ └── Question.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── .travis │ └── travis.enc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README-zh-cn.md ├── README.md ├── assets │ ├── alipay.jpg │ ├── community.md │ ├── cover-2nd-en-logo.png │ ├── cover-2nd-en.afphoto │ ├── cover-2nd-en.png │ ├── cover-2nd-logo.png │ ├── cover-2nd.afphoto │ ├── cover-2nd.png │ ├── cover-2nd.psd │ ├── donate.md │ ├── figures │ │ ├── comparison.png │ │ ├── pointers1.png │ │ ├── pointers1_en.png │ │ └── pointers2.png │ ├── qq-group.png │ └── wechat.jpg ├── book │ ├── en-us │ │ ├── 00-preface.md │ │ ├── 01-intro.md │ │ ├── 02-usability.md │ │ ├── 03-runtime.md │ │ ├── 04-containers.md │ │ ├── 05-pointers.md │ │ ├── 06-regex.md │ │ ├── 07-thread.md │ │ ├── 08-filesystem.md │ │ ├── 09-others.md │ │ ├── 10-cpp20.md │ │ ├── appendix1.md │ │ ├── appendix2.md │ │ └── toc.md │ └── zh-cn │ │ ├── 00-preface.md │ │ ├── 01-intro.md │ │ ├── 02-usability.md │ │ ├── 03-runtime.md │ │ ├── 04-containers.md │ │ ├── 05-pointers.md │ │ ├── 06-regex.md │ │ ├── 07-thread.md │ │ ├── 08-filesystem.md │ │ ├── 09-others.md │ │ ├── 10-cpp20.md │ │ ├── appendix1.md │ │ ├── appendix2.md │ │ ├── appendix3.md │ │ └── toc.md ├── code │ ├── 1 │ │ ├── 1.1.c.and.cpp │ │ ├── Makefile │ │ ├── foo.c │ │ └── foo.h │ ├── 2 │ │ ├── 2.01.nullptr.cpp │ │ ├── 2.02.constexpr.cpp │ │ ├── 2.03.if.switch.cpp │ │ ├── 2.04.initializer.list.cpp │ │ ├── 2.05.structured.binding.cpp │ │ ├── 2.06.auto.cpp │ │ ├── 2.07.decltype.cpp │ │ ├── 2.08.tail.return.type.cpp │ │ ├── 2.09.decltype.auto.cpp │ │ ├── 2.10.if.constexpr.cpp │ │ ├── 2.11.for.loop.cpp │ │ ├── 2.12.external.template.cpp │ │ ├── 2.13.alias.template.cpp │ │ ├── 2.14.default.template.param.cpp │ │ ├── 2.15.variadic.template.param.cpp │ │ ├── 2.16.fold.expression.cpp │ │ ├── 2.18.non.type.template.auto.cpp │ │ ├── 2.19.delegate.constructor.cpp │ │ ├── 2.20.strong.type.enum.cpp │ │ └── Makefile │ ├── 3 │ │ ├── 3.1.lambda.basic.cpp │ │ ├── 3.2.function.wrap.cpp │ │ ├── 3.3.rvalue.cpp │ │ ├── 3.4.historical.cpp │ │ ├── 3.5.move.semantics.cpp │ │ ├── 3.6.move.semantics.cpp │ │ ├── 3.7.perfect.forward.cpp │ │ └── Makefile │ ├── 4 │ │ ├── 4.1.linear.container.cpp │ │ ├── 4.2.unordered.map.cpp │ │ ├── 4.3.tuples.cpp │ │ └── Makefile │ ├── 5 │ │ ├── 5.1.shared.ptr.a.cpp │ │ ├── 5.2.unique.ptr.cpp │ │ ├── 5.3.weak.ptr.cpp │ │ └── Makefile │ ├── 6 │ │ ├── 6.1.regex.cpp │ │ └── Makefile │ ├── 7 │ │ ├── 7.1.thread.basic.cpp │ │ ├── 7.2.critical.section.a.cpp │ │ ├── 7.3.critical.section.b.cpp │ │ ├── 7.4.futures.cpp │ │ ├── 7.5.producer.consumer.cpp │ │ ├── 7.6.atomic.cpp │ │ ├── 7.6.bad.example.cpp │ │ ├── 7.7.is.lock.free.cpp │ │ ├── 7.8.memory.order.cpp │ │ └── Makefile │ ├── 9 │ │ ├── 9.1.noexcept.cpp │ │ ├── 9.2.literals.cpp │ │ ├── 9.3.alignment.cpp │ │ └── Makefile │ └── 10 │ │ ├── 10.1.without.concepts.cpp │ │ ├── 10.2.concepts.cpp │ │ └── Makefile ├── docker │ └── Dockerfile ├── epub │ ├── en-us │ │ ├── Makefile │ │ └── filter.py │ └── zh-cn │ │ ├── Makefile │ │ └── filter.py ├── exercises │ ├── 2 │ │ ├── fold.expresion.cpp │ │ └── structured.binding.cpp │ ├── 6 │ │ ├── Makefile │ │ ├── handler.hpp │ │ ├── main.http.cpp │ │ ├── main.https.cpp │ │ ├── server.base.hpp │ │ ├── server.http.hpp │ │ ├── server.https.hpp │ │ └── www │ │ │ ├── index.html │ │ │ └── test.html │ └── 7 │ │ ├── 7.1 │ │ ├── Makefile │ │ ├── main.cpp │ │ └── thread_pool.hpp │ │ ├── 7.2.mutex.cpp │ │ └── Makefile ├── pdf │ ├── en-us │ │ ├── Makefile │ │ ├── aggregator.py │ │ └── meta │ │ │ └── template.tex │ └── zh-cn │ │ ├── Makefile │ │ ├── aggregator.py │ │ └── meta │ │ └── template.tex └── website │ ├── Makefile │ ├── README.md │ ├── _config.yml │ ├── filter.py │ ├── install.js │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── _posts │ │ └── index.md │ └── modern-cpp │ │ ├── about │ │ ├── ack.md │ │ └── copyright.md │ │ └── assets │ │ ├── check.png │ │ ├── down.png │ │ ├── feed.png │ │ ├── lang │ │ ├── cn.svg │ │ ├── de.svg │ │ └── en.svg │ │ ├── menu.png │ │ └── search.png │ └── themes │ └── moderncpp │ ├── _config.yml │ ├── layout │ ├── index.ejs │ ├── layout.ejs │ ├── page.ejs │ ├── partials │ │ ├── header.ejs │ │ ├── main_menu.ejs │ │ ├── main_menu_en.ejs │ │ ├── sidebar.ejs │ │ └── toc.ejs │ └── post.ejs │ └── source │ └── modern-cpp │ ├── css │ ├── _animations.styl │ ├── _common.styl │ ├── _header.styl │ ├── _settings.styl │ ├── _sidebar.styl │ ├── _syntax.styl │ ├── index.styl │ └── page.styl │ └── js │ └── common.js ├── modern-cpp-tutorial-en-us.pdf └── modern-cpp-tutorial-zh-cn.pdf /github_code/.github/ISSUE_TEMPLATE/Bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: 报告错误 4 | 5 | --- 6 | 7 | 8 | 9 | ## Actual Description 10 | 11 | - File Path: for example, `book/en-us/02-usability.md` 12 | - Original paragraph: 13 | 14 | ``` 15 | A copy of the original paragraph 16 | ``` 17 | 18 | ## Expected Description 19 | 20 | ``` 21 | A modified paragraph 22 | ``` 23 | 24 | ## Attachments 25 | 26 | Attach screenshot or files if necessary. 27 | 28 | --- 29 | 30 | 31 | 32 | ## 实际描述 33 | 34 | - 文件路径:例如,book/zh-cn/02-usability.md 35 | - 原文段落: 36 | 37 | ``` 38 | 复制原文段落 39 | ``` 40 | 41 | ## 预期描述 42 | 43 | ``` 44 | 修改后的段落 45 | ``` 46 | 47 | ## 附图 48 | 49 | 必要时,请附上相关截图 -------------------------------------------------------------------------------- /github_code/.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: 内容建议 4 | 5 | --- 6 | 7 | 8 | 9 | ## Motivation 10 | 11 | Please briefly describe your motivation. 12 | 13 | ## Requirements 14 | 15 | Please list all of your suggestions. 16 | 17 | --- 18 | 19 | 20 | 21 | ## 动机 22 | 23 | 请描述你提交内容建议的动机。 24 | 25 | ## 需求说明 26 | 27 | 请描述你提交内容建议的详单,例如具体是增加哪个知识点的说明。 -------------------------------------------------------------------------------- /github_code/.github/ISSUE_TEMPLATE/Question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: 提交问题 4 | 5 | --- 6 | 7 | 8 | 9 | ## Question 10 | 11 | Please describe your question here, and read [How-To-Ask-Questions-The-Smart-Way](http://www.catb.org/~esr/faqs/smart-questions.html) before you submit your question. 12 | 13 | --- 14 | 15 | 16 | 17 | ## 问题描述 18 | 19 | 请在此描述你的问题,提问前请参考[提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md) -------------------------------------------------------------------------------- /github_code/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | resolve #issue_id 2 | 3 | 4 | 5 | ## Description 6 | 7 | Please describe the motivation of this pull request, and what problem was solved in this PR. 8 | 9 | ## Change List 10 | 11 | - Fix typo error of XXX 12 | - Add description regarding XXX feature 13 | - Resolve error content of XXX 14 | 15 | ## Reference 16 | 17 | Please add reference if necessary 18 | 19 | --- 20 | 21 | 22 | 23 | ## 说明 24 | 25 | 此处详细说明 PR 的动机是什么、解决了什么样的问题。 26 | 27 | ## 变化箱单 28 | 29 | - 修复了 XXX 的 typo 错误 30 | - 增加了 XXX 相关的说明 31 | - 解决了关于 XXX 的描述性错误 32 | 33 | ## 参考文献 34 | 35 | 如果有请注明 -------------------------------------------------------------------------------- /github_code/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | 31 | .vscode 32 | 33 | node_modules 34 | 35 | pdf/zh-cn/*.md 36 | 37 | website/db.json 38 | website/public/* 39 | website/src/modern-cpp/zh-cn/* 40 | website/src/modern-cpp/en-us/* 41 | website/src/modern-cpp/exercises 42 | website/src/modern-cpp/code 43 | website/src/modern-cpp/assets/cover-2nd-en.png 44 | website/src/modern-cpp/assets/cover-2nd.png 45 | website/src/modern-cpp/assets/figures/* -------------------------------------------------------------------------------- /github_code/.travis.yml: -------------------------------------------------------------------------------- 1 | services: 2 | - docker 3 | 4 | before_install: 5 | - openssl aes-256-cbc -K $encrypted_9157553ce13c_key -iv $encrypted_9157553ce13c_iv -in .travis/travis.enc -out ~/.ssh/id_rsa -d 6 | - chmod 600 ~/.ssh/id_rsa 7 | - git config --global user.name "Changkun Ou" 8 | - git config --global user.email "hi@changkun.us" 9 | 10 | addons: 11 | ssh_known_hosts: 12 | - changkun.de 13 | 14 | script: 15 | - make build 16 | 17 | after_success: 18 | scp -r website/public/modern-cpp/* $encrypted_server_user@changkun.de:$encrypted_server_path 19 | -------------------------------------------------------------------------------- /github_code/.travis/travis.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/.travis/travis.enc -------------------------------------------------------------------------------- /github_code/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at hi at changkun dot us. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /github_code/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | ## Submit Issue 4 | 5 | C++ 11/14/17 issue is used to track the principle description error, `typo` error, and the questions to the author of the book. 6 | 7 | - 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. 8 | 9 | - Do not hesitate to submit a `principle` error because it will prevent wrong knowledge being spread. 10 | Report the error immediately by [submitting issue](https://github.com/changkun/modern-cpp-tutorial/issues) to avoid the propogation of wrong knowledge. 11 | 12 | - 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. 13 | 14 | - 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. 15 | 16 | ## Pull Request 17 | 18 | "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: 19 | 20 | - 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. 21 | 22 | - Make sure your PR has improved more than 50 `typo` errors, otherwise please do not submit a PR. 23 | 24 | - For a PR that fixes principled errors, please don't hesitate, all of the readers of the book are very grateful for your contribution! 25 | 26 | - If you would like to be a co-author of this book, please send an email to ask: `hi at changkun dot us`. 27 | 28 | Since this repository provides a variety of reading approaches, thus make sure you have checked all items in the following checklist: 29 | 30 | - [ ] 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; 31 | - [ ] 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; 32 | - [ ] If your changes also involve the exercises, you also need to synchronize the contents of the `exercises` folder. 33 | 34 | # 如何参与贡献 35 | 36 | ## 提交 Issue 37 | 38 | 『C++ 11/14/17/20』的 issue 用于追踪书中存在的原则性的描述错误、存在的 `typo` 错误,以及向本书作者提问等。 39 | 40 | - 通常情况下,你可能会发现书中某个段落存在错别字、语义错误、文法错误等。 41 | 这都是 `typo` 错误。如果该错误已经对你的阅读造成了一定障碍, 42 | 你也强烈的认为该 `typo` 也会影响到其他人的阅读, 43 | 那么非常欢迎[提交 issue](https://github.com/changkun/modern-cpp-tutorial/issues) 44 | 来报告 `typo` 错误。 45 | 46 | - 对于书中存在的原则性错误,例如对源码进行分析的内容产生明显的错误、 47 | 且内容对其他人会产生严重的误导,请不要犹豫, 48 | 立即[提交 issue](https://github.com/changkun/modern-cpp-tutorial/issues) 来报告此错误,以免继续传播错误的知识。 49 | 如果可以,也请附上相关改进说明。通常情况下,如果存在这类问题,我们鼓励你一并提交改进 PR。 50 | 51 | - 如果你在阅读本书的时候发现有部分内容难于理解,也欢迎[提交 issue](https://github.com/changkun/modern-cpp-tutorial/issues) 来询问作者表达你的疑惑。 52 | 作者会根据实际情况重新优化这一部分的内容,进而帮助他人更易阅读这部分的内容。 53 | 54 | - 我们也欢迎你提交针对本书内容的相关建议,具体来说如果你认为书中未涉及的某个模块或者文件的源码值得讨论,也欢迎 [提交 issue](https://github.com/changkun/go-under-the-hood/issues) 来进一步讨论。 55 | 56 | ## 提交 Pull request 57 | 58 | 『C++ 11/14/17/20』是一本开源书籍,任何人都可以参与贡献自己 PR。但在提交 PR 之前请仔细阅读下面的说明: 59 | 60 | - 当你认为需要提交一个 PR 时,请确保 [issue 列表](https://github.com/changkun/modern-cpp-tutorial/issues)中,已经包含了你想要解决的问题。 61 | 如果没有,请参考**提交 Issue** 一节中的描述,提交你的 issue,再提交你的 PR。 62 | 63 | - 当你准备提交一个 typo 错误的 PR 时,请确保你的 PR 改进了 **超过 50 个汉字(或英文单词)** 的 `typo` 错误,否则请不要提交 PR。 64 | - 对于一个修复原则性错误的 PR,请不要犹豫,笔者对此表示非常感谢! 65 | - 如果非常喜欢本书,以至于希望参与本书的合著,成为作者,请发邮件询问:`hi at changkun dot us`。 66 | 67 | 本仓库提供了多种阅读方式,如果你提交一个 Pull request,则请确保你检查的如下的 checklist: 68 | 69 | - [ ] 只改动原书正文 `book` 下的部分内容,不涉及代码片段的修改,则无需进行修改 70 | - [ ] 如果同时还改动了正文中的代码片段,则需要同步 `code` 文件夹下对应的代码片段 71 | - [ ] 如果改动还涉及习题的设计,则需要同步 `exercises` 文件夹下的内容 72 | -------------------------------------------------------------------------------- /github_code/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - 2019 Changkun Ou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /github_code/Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_ENV=changkun/modern-cpp-tutorial:build-env 2 | TARGET = pdf epub 3 | LANGS = zh-cn en-us 4 | ALL_BUILDS = website $(TARGET) 5 | 6 | # dep 7 | 8 | all: $(ALL_BUILDS) 9 | 10 | $(TARGET): $(LANGS) 11 | mkdir -p website/public/modern-cpp/$@/ 12 | for lang in $^ ; do \ 13 | cd $@/$${lang} && make && make clean && cd ../..; \ 14 | mv $@/$${lang}/modern-cpp-tutorial.$@ website/public/modern-cpp/$@/modern-cpp-tutorial-$${lang}.$@; \ 15 | done 16 | 17 | website: 18 | cd website && make 19 | 20 | build: 21 | docker run --rm -v `pwd`:/modern-cpp-tutorial -it $(DOCKER_ENV) make 22 | 23 | # dev 24 | 25 | build-env: 26 | docker build -t $(DOCKER_ENV) -f ./docker/Dockerfile . 27 | 28 | serve: 29 | cd website && make s 30 | 31 | clean: 32 | cd pdf/zh-cn && make clean 33 | cd pdf/en-us && make clean 34 | cd website && make clean 35 | docker images -f "dangling=true" -q | xargs docker rmi -f 36 | docker image prune -f 37 | 38 | .PHONY : $(LANGS) $(ALL_BUILDS) serve build-env build-all clean -------------------------------------------------------------------------------- /github_code/README-zh-cn.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 | # 现代 C++ 教程:高速上手 C++11/14/17/20 4 | 5 | ![](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) 6 | 7 | ## 本书目的 8 | 9 | 本书号称『高速上手』,从内容上对二十一世纪二十年代之前产生 C++ 的相关特性做了非常相对全面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容。这些特性并不需要全部掌握,只需针对自己的使用需求和特定的应用场景,学习、查阅最适合自己的新特性即可。 10 | 11 | 同时,本书在介绍这些特性的过程中,尽可能简单明了的介绍了这些特性产生的历史背景和技术需求,这为理解这些特性、运用这些特性提供了很大的帮助。 12 | 13 | 此外,笔者希望读者在阅读本书后,能够努力在新项目中直接使用现代 C++,并努力将旧项目逐步迁移到现代 C++。也算是笔者为推进现代 C++ 的普及贡献了一些绵薄之力。 14 | 15 | ## 目标读者 16 | 17 | 1. 本书假定读者已经熟悉了传统 C++ ,至少在阅读传统 C++ 代码上不具备任何困难。换句话说,那些长期使用传统 C++进行编码的人、渴望在短时间内迅速了解**现代 C++** 特性的人非常适合阅读本书; 18 | 2. 本书一定程度上介绍了一些现代 C++ 的**黑魔法**,但这些魔法毕竟有限,不适合希望进阶学习现代 C++ 的读者,本书的定位系**现代 C++ 的快速上手**。当然,希望进阶学习的读者可以使用本书来回顾并检验自己对 **现代 C++** 的熟悉度。 19 | 20 | ## 开始阅读 21 | 22 | 你可以选择以下几种阅读方式: 23 | 24 | 1. [GitHub 在线](./book/zh-cn/toc.md) 25 | 2. [PDF 文档](https://changkun.de/modern-cpp/modern-cpp-tutorial-zh-cn.pdf) 26 | 3. [EPUB 文档](https://changkun.de/modern-cpp/epub/modern-cpp-tutorial-zh-cn.epub) 27 | 4. [网站](https://changkun.de/modern-cpp/) 28 | 29 | ## 相关代码 30 | 31 | 本书每章中都出现了大量的代码,如果你在跟随本书介绍特性的思路编写自己的代码遇到问题时,不妨读一读随书附上的源码,你可以在[这里](./code)中找到书中介绍过的全部的源码,所有代码按章节组织,文件夹名称为章节序号。 32 | 33 | ## 随书习题 34 | 35 | 本书每章最后还加入了少量难度极小的习题,仅用于检验你是否能混合运用当前章节中的知识点。你可以在[这里](./exercises)找到习题的答案,文件夹名称为章节序号。 36 | 37 | ## 本书网站 38 | 39 | 本书的[网站](https://changkun.de/modern-cpp)源码可以在[这里](./website)找到,由 [hexo](https://hexo.io) 和 [vuejs](https://vuejs.org) 协同构建而成。网站旨在提供一个除 GitHub 之外的阅读方式,除了在桌面端访问之外,你也可以在移动端上阅读本书。 40 | 41 | ## 构建 42 | 43 | 如果你希望在本地编译整个仓库,我们建议使用 [Docker](https://docs.docker.com/install/)。如果 Docker 在你的本地能正常使用,则可以简单的通过运行下面的指令完成构建: 44 | 45 | ```bash 46 | $ make build 47 | ``` 48 | 49 | ## 致谢 50 | 51 | 笔者时间和水平有限,如果读者发现书中内容的错误,欢迎提 [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)。 52 | 53 |

本项目还由以下产品提供赞助支持:

54 |

55 | 56 | 57 | 58 |

59 | 60 | ## 许可 61 | 62 | 知识共享许可协议 63 | 64 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](./LICENSE)。 65 | -------------------------------------------------------------------------------- /github_code/README.md: -------------------------------------------------------------------------------- 1 | logo 2 | 3 | # Modern C++ Tutorial: C++11/14/17/20 On the Fly 4 | 5 | ![](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) 6 | 7 | ## Purpose 8 | 9 | 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). 10 | 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. 11 | Readers should be aware that not all of these features are required. Instead, it should be learned when you really need it. 12 | 13 | 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. 14 | 15 | 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. 16 | 17 | ## Targets 18 | 19 | - 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. 20 | 21 | - 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++. 22 | 23 | ## Start 24 | 25 | You can choose from the following reading methods: 26 | 27 | - [GitHub Online](./book/en-us/toc.md) 28 | - [PDF document](https://changkun.de/modern-cpp/pdf/modern-cpp-tutorial-en-us.pdf) 29 | - [EPUB document](https://changkun.de/modern-cpp/epub/modern-cpp-tutorial-en-us.epub) 30 | - [Website](https://changkun.de/modern-cpp) 31 | 32 | ## Code 33 | 34 | 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. 35 | 36 | ## Exercises 37 | 38 | There are few exercises at the end of each chapter of the book. These are ment 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. 39 | 40 | ## Website 41 | 42 | 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. 43 | 44 | ## Build 45 | 46 | If you are interested in building everything locally, it is recommended using [Docker](https://docs.docker.com/install/). To build, simply run: 47 | 48 | ```bash 49 | $ make build 50 | ``` 51 | 52 | ## Acknowledgements 53 | 54 | This book was originally written in Chinese by [Changkun Ou](https://changkun.de). 55 | 56 | 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). 57 | 58 | The author is grateful to all contributors, including but not limited to [Contributors](https://github.com/changkun/modern-cpp-tutorial/graphs/contributors). 59 | 60 |

This project is also supported by:

61 |

62 | 63 | 64 | 65 |

66 | 67 | ## Licenses 68 | 69 | 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). 70 | -------------------------------------------------------------------------------- /github_code/assets/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/alipay.jpg -------------------------------------------------------------------------------- /github_code/assets/community.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 社区 3 | type: about 4 | order: 2 5 | --- 6 | 7 | ## Community 8 | 9 | The book offers a telegram chat group, feel free to join if you are interested: 10 | 11 | [![](https://img.shields.io/badge/chat-telegram-blue.svg?style=popout-square&logo=telegram)](https://t.me/joinchat/FEeulBM5OVYzuDI4phQ9Mg) 12 | -------------------------------------------------------------------------------- /github_code/assets/cover-2nd-en-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd-en-logo.png -------------------------------------------------------------------------------- /github_code/assets/cover-2nd-en.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd-en.afphoto -------------------------------------------------------------------------------- /github_code/assets/cover-2nd-en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd-en.png -------------------------------------------------------------------------------- /github_code/assets/cover-2nd-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd-logo.png -------------------------------------------------------------------------------- /github_code/assets/cover-2nd.afphoto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd.afphoto -------------------------------------------------------------------------------- /github_code/assets/cover-2nd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd.png -------------------------------------------------------------------------------- /github_code/assets/cover-2nd.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/cover-2nd.psd -------------------------------------------------------------------------------- /github_code/assets/donate.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 资助 3 | type: about 4 | order: 1 5 | --- 6 | 7 | ## Donate 8 | 9 | I would love if you support me to make the book better: 10 | 11 | [![](https://img.shields.io/badge/donate-PayPal-104098.svg?style=popout-square&logo=PayPal)](https://www.paypal.me/changkunde/4.99eur) 12 | 13 | ## 资助 14 | 15 | 如果你认为本书对你起到了帮助,并希望赞助作者,可以通过下面的二维码给予支持: 16 | 17 | |微信|支付宝| 18 | |:--:|:--:| 19 | |![](../assets/wechat.jpg) | ![](../assets/alipay.jpg)| 20 | 21 | -------------------------------------------------------------------------------- /github_code/assets/figures/comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/figures/comparison.png -------------------------------------------------------------------------------- /github_code/assets/figures/pointers1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/figures/pointers1.png -------------------------------------------------------------------------------- /github_code/assets/figures/pointers1_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/figures/pointers1_en.png -------------------------------------------------------------------------------- /github_code/assets/figures/pointers2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/figures/pointers2.png -------------------------------------------------------------------------------- /github_code/assets/qq-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/qq-group.png -------------------------------------------------------------------------------- /github_code/assets/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/assets/wechat.jpg -------------------------------------------------------------------------------- /github_code/book/en-us/00-preface.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Preface 3 | type: book-en-us 4 | order: 0 5 | --- 6 | 7 | # Preface 8 | 9 | [TOC] 10 | 11 | ## Introduction 12 | 13 | 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. 14 | 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. 15 | 16 | **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. 17 | 18 | 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++. 19 | 20 | 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. 21 | 22 | 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. 23 | 24 | ## Targets 25 | 26 | - 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; 27 | 28 | - 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++. 29 | 30 | ## Purpose 31 | 32 | The book claims "On the Fly". Its intent is to provide a comprehensive introduction to the relevant features regarding modern C++ (before 2020s). 33 | 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. 34 | Readers should aware that all of these features are not required. It should be leart when you really need it. 35 | 36 | 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. 37 | 38 | 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. 39 | 40 | ## Code 41 | 42 | 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. 43 | 44 | ## Exercises 45 | 46 | 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. 47 | 48 | [Table of Content](./toc.md) | [Next Chapter: Towards Modern C++](./01-intro.md) 49 | 50 | ## Licenses 51 | 52 | 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). -------------------------------------------------------------------------------- /github_code/book/en-us/08-filesystem.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Chapter 08 File System" 3 | type: book-en-us 4 | order: 8 5 | --- 6 | 7 | # Chapter 08 File System 8 | 9 | [TOC] 10 | 11 | The file system library provides functions related to 12 | the operation of the file system, path, regular files, directories, and so on. 13 | Similar to the regular expression library, he was one of the first libraries 14 | to be launched by boost and eventually merged into the C++ standard. 15 | 16 | ## 8.1 Document and Link 17 | 18 | TODO: 19 | 20 | ## 8.2 std::filesystem 21 | 22 | TODO: 23 | 24 | [Table of Content](./toc.md) | [Previous Chapter](./07-thread.md) | [Next Chapter: Minor Features](./09-others.md) 25 | 26 | ## Further Readings 27 | 28 | ## Licenses 29 | 30 | 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). -------------------------------------------------------------------------------- /github_code/book/en-us/10-cpp20.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Chapter 10 Outlook: Introduction of C++20" 3 | type: book-en-us 4 | order: 10 5 | --- 6 | 7 | # Chapter 10 Outlook: Introduction of C++20 8 | 9 | [TOC] 10 | 11 | C++20 seems to be an exciting update. 12 | For example, as early as C++11, the `Concept`, 13 | which was eager to call for high-altitude but ultimately lost, is now on the line. 14 | The C++ Organizing Committee decided to vote to finalize C++20 with many proposals, 15 | such as **Concepts**/**Module**/**Coroutine**/**Ranges**/ and so on. 16 | In this chapter we'll take a look at some of the important features that 17 | C++20 will introduce. 18 | 19 | ## Concept 20 | 21 | Concept is a further enhancement to C++ template programming. 22 | In simple terms, the concept is a compile-time feature. 23 | It allows the compiler to evaluate template parameters at compile time, 24 | greatly enhancing our experience with template programming in C++. 25 | When programming with templates, we often encounter a variety of heinous errors. 26 | This is because we have so far been unable to check and limit template parameters. 27 | For example, the following two lines of code can cause a lot of 28 | almost unreadable compilation errors: 29 | 30 | ```cpp 31 | #include 32 | #include 33 | int main() { 34 | std::list l = {1, 2, 3}; 35 | std::sort(l.begin(), l.end()); 36 | return 0; 37 | } 38 | ``` 39 | 40 | The root cause of this code error is that `std::sort` must provide 41 | a random iterator for the sorting container, otherwise it will not be used, 42 | and we know that `std::list` does not support random access. 43 | In the conceptual language, the iterator in `std::list` does not satisfy 44 | the constraint of the concept of random iterators in `std::sort`. 45 | After introducing the concept, we can constrain the template parameters 46 | like this: 47 | 48 | ```cpp 49 | template 50 | requires Sortable // Sortable is a concept 51 | void sort(T& c); 52 | ``` 53 | 54 | abbreviate as: 55 | 56 | ```cpp 57 | template // T is a Sortable typename 58 | void sort(T& c) 59 | ``` 60 | 61 | Even use it directly as a type: 62 | 63 | ```cpp 64 | void sort(Sortable& c); // c is a Sortable type object 65 | ``` 66 | 67 | Let's look at a practical example. 68 | 69 | TODO: 70 | 71 | ## Module 72 | 73 | TODO: 74 | 75 | ## Contract 76 | 77 | TODO: 78 | 79 | ## Range 80 | 81 | TODO: 82 | 83 | ## Coroutine 84 | 85 | TODO: 86 | 87 | ## Conclusion 88 | 89 | In general, I finally saw the exciting features of Concepts/Ranges/Modules in C++20. 90 | This is still full of charm for a programming language that is already in its thirties. 91 | 92 | [Table of Content](./toc.md) | [Previous Chapter](./09-others.md) | [Next Chapter](./appendix1.md) 93 | 94 | ## Further Readings 95 | 96 | - [Why Concepts didn't make C++17?](http://honermann.net/blog/2016/03/06/why-concepts-didnt-make-cxx17/) 97 | - [C++11/14/17/20 Compiler Support](http://en.cppreference.com/w/cpp/compiler_support) 98 | - [C++ History](https://en.cppreference.com/w/cpp/language/history) 99 | 100 | ## Licenses 101 | 102 | 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). -------------------------------------------------------------------------------- /github_code/book/en-us/appendix1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Appendix 1: Further Study Materials" 3 | type: book-en-us 4 | order: 11 5 | --- 6 | 7 | # Appendix 1: Further Study Materials 8 | 9 | First of all, congratulations 🎉 on reading this book! I hope this book has raised your interest in modern C++. 10 | 11 | As mentioned in the introduction to this book, this book is just a book that takes you quickly to the new features of modern C++ 11/14/17/20, rather than the advanced learning practice of C++ "Black Magic". The author of course also thinks about this demand, but the content is very difficult and there are few audiences. Here, the author lists some materials that can help you learn more about modern C++ based on this book. I hope I can help you: 12 | 13 | - [C++ Reference](http://en.cppreference.com/w) 14 | - [CppCon YouTube Channel](https://www.youtube.com/user/CppCon/videos) 15 | - [Ulrich Drepper. What Every Programmer Should Know About Memory. 2007](https://people.freebsd.org/~lstewart/articles/cpumemory.pdf) 16 | - to be added 17 | 18 | [Table of Content](./toc.md) | [Previous Chapter](./10-cpp20.md) | [Next Chapter](./appendix2.md) 19 | 20 | ## Licenses 21 | 22 | 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). -------------------------------------------------------------------------------- /github_code/book/en-us/appendix2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Appendix 2: Modern C++ Best Practices" 3 | type: book-en-us 4 | order: 12 5 | --- 6 | 7 | # Appendix 2: Modern C++ Best Practices 8 | 9 | In this appendix we will briefly talk about the best practices of modern C++. In general, the author's thoughts on C++'s best practices are mainly absorbed from [Effective Modern C++](https://www.amazon.com/dp/1491903996/ref=cm_sw_em_r_mt_dp_U_-ZgjDb81ERBNP) and [C++ Style Guide](https://google.github.io/styleguide/cppguide.html). In this appendix, we will briefly discuss and use the actual examples to illustrate the methods, and introduce some of **the author's personal**, **non-common**, **non-sensible** best practices, and how to ensure the overall quality of the code. 10 | 11 | ## Common Tools 12 | 13 | TODO: 14 | 15 | ## Coding Style 16 | 17 | TODO: 18 | 19 | ## Overall Performance 20 | 21 | TODO: 22 | 23 | ## Code Security 24 | 25 | TODO: 26 | 27 | ## Maintainability 28 | 29 | TODO: 30 | 31 | ## Portability 32 | 33 | TODO: 34 | 35 | [Table of Content](./toc.md) | [Previous Chapter](./appendix1.md) 36 | 37 | ## Licenses 38 | 39 | 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). -------------------------------------------------------------------------------- /github_code/book/en-us/toc.md: -------------------------------------------------------------------------------- 1 | # C++ 11/14/17/20 On The Fly 2 | 3 | ## Table of Contents 4 | 5 | - [**Preface**](./00-preface.md) 6 | - [**Chapter 01 Towards Modern C++**](./01-intro.md) 7 | + 1.1 Deprecated Features 8 | + 1.2 Compatibility with C 9 | + Further Readings 10 | - [**Chapter 02 Language Usability Enhancements**](./02-usability.md) 11 | + 2.1 Constants 12 | - nullptr 13 | - constexpr 14 | + 2.2 Variables & Initialization 15 | - Conditional Statement 16 | - Initializer List 17 | - Structured binding 18 | + 2.3 Type Deduction 19 | - auto 20 | - decltype 21 | - Tail return type 22 | - decltype(auto) 23 | + 2.4 Control Flow 24 | - if constexpr 25 | - Range-based for loop 26 | + 2.5 Templates 27 | - External templates 28 | - The ">" 29 | - Type alias templates 30 | - Default template parameters 31 | - Variadic templates 32 | - Fold expression 33 | - Non-type template parameter deduction 34 | + 2.6 Object-oriented 35 | - Delegate constructor 36 | - Inheritance constructor 37 | - Explicit virtual function overwrite 38 | - override 39 | - final 40 | - Explicit delete default function 41 | - Strongly typed enumerations 42 | - [**Chapter 03 Language Runtime Enhancements**](./03-runtime.md) 43 | + 3.1 Lambda expression 44 | + Basics 45 | + Generics 46 | + 3.2 Function object wrapper 47 | + std::function 48 | + std::bind/std::placeholder 49 | + 3.3 rvalue reference 50 | + lvalue, rvalue, prvalue, xvalue 51 | + rvalue reference and lvalue reference 52 | + Move semantics 53 | + Perfect forwarding 54 | - [**Chapter 04 Containers**](./04-containers.md) 55 | + 4.1 Linear containers 56 | + `std::array` 57 | + `std::forward_list` 58 | + 4.2 Unordered containers 59 | + `std::unordered_set` 60 | + `std::unordered_map` 61 | + 4.3 Tuples `std::tuple` 62 | + basic operation 63 | + runtime indexing `std::variant` 64 | + merge and iteration 65 | - [**Chapter 05 Smart Pointers and Memory Management**](./05-pointers.md) 66 | + 5.1 RAII and reference counting 67 | + 5.2 `std::shared_ptr` 68 | + 5.3 `std::unique_ptr` 69 | + 5.4 `std::weak_ptr` 70 | - [**Chapter 06 Regular Expression**](./06-regex.md) 71 | + 6.1 Introduction 72 | + Ordinary characters 73 | + Special characters 74 | + Quantifiers 75 | + 6.2 `std::regex` and its related 76 | + `std::regex` 77 | + `std::regex_match` 78 | + `std::match_results` 79 | - [**Chapter 07 Parallelism and Concurrency**](./07-thread.md) 80 | + 7.1 Basic of Parallelism 81 | + 7.2 Mutex and Critical Section 82 | + 7.3 Futures 83 | + 7.4 Condition Variable 84 | + 7.5 Atomic Operation and Memory Model 85 | + Atomic Operation 86 | + Consistency Model 87 | + Memory Orders 88 | - [**Chapter 08 File System**](./08-filesystem.md) 89 | + 8.1 Documents and links 90 | + 8.2 `std::filesystem` 91 | - [**Chapter 09 Minor Features**](./09-others.md) 92 | + 9.1 New Types 93 | + `long long int` 94 | + 9.2 `noexcept` and Its Operations 95 | + 9.3 Literal 96 | + Raw String Literal 97 | + Custom String Literal 98 | + 9.4 Memory Alignment 99 | - [**Chapter 10 Outlook: Introduction of C++20**](./10-cpp20.md) 100 | + 10.1 Concept 101 | + 10.2 Range 102 | + 10.3 Module 103 | + 10.4 Coroutine 104 | + 10.5 Transaction Memory 105 | - [**Appendix 1: Further Study Materials**](./appendix1.md) 106 | - [**Appendix 2: Modern C++ Best Practices**](./appendix2.md) 107 | 108 | Table of Content | Last Chapter | [Next Chapter: Preface](./00-preface.md) 109 | 110 | ## Licenses 111 | 112 | 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). -------------------------------------------------------------------------------- /github_code/book/zh-cn/00-preface.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 序言 3 | type: book-zh-cn 4 | order: 0 5 | --- 6 | 7 | # 序言 8 | 9 | [TOC] 10 | 11 | ## 引言 12 | 13 | C++ 是一个用户群体相当大的语言。从 C++98 的出现到 C++11 的正式定稿经历了长达十年多之久的积累。C++14/17 则是作为对 C++11 的重要补充和优化,C++20 则将这门语言领进了现代化的大门,所有这些新标准中扩充的特性,给 C++ 这门语言注入了新的活力。 14 | 那些还在坚持使用**传统 C++**(本书把 C++98 及其之前的 C++ 特性均称之为传统 C++)而未接触过现代 C++ 的 C++ 程序员在见到诸如 Lambda 表达式这类全新特性时,甚至会流露出『学的不是同一门语言』的惊叹之情。 15 | 16 | **现代 C++** (本书中均指 C++11/14/17/20) 为传统 C++ 注入的大量特性使得整个 C++ 变得更加像一门现代化的语言。现代 C++ 不仅仅增强了 C++ 语言自身的可用性,`auto` 关键字语义的修改使得我们更加有信心来操控极度复杂的模板类型。同时还对语言运行期进行了大量的强化,Lambda 表达式的出现让 C++ 具有了『匿名函数』的『闭包』特性,而这一特性几乎在现代的编程语言(诸如 Python/Swift/... )中已经司空见惯,右值引用的出现解决了 C++ 长期以来被人诟病的临时对象效率问题等等。 17 | 18 | C++17 则是近三年依赖 C++ 社区一致推进的方向,也指出了**现代C++**编程的一个重要发展方向。尽管它的出现并不如 C++11 的分量之重,但它包含了大量小而美的语言与特性(例如结构化绑定),这些特性的出现再一次修正了我们在 C++ 中的编程范式。 19 | 20 | 现代 C++ 还为自身的标准库增加了非常多的工具和方法,诸如在语言自身标准的层面上制定了 `std::thread`,从而支持了并发编程,在不同平台上不再依赖于系统底层的 API,实现了语言层面的跨平台支持;`std::regex` 提供了完整的正则表达式支持等等。C++98 已经被实践证明了是一种非常成功的『范型』,而现代 C++ 的出现,则进一步推动这种范型,让 C++ 成为系统程序设计和库开发更好的语言。Concept 提供了对模板参数编译期的检查,进一步增强了语言整体的可用性。 21 | 22 | 总而言之,我们作为 C++ 的拥护与实践者,始终保持接纳新事物的开放心态,才能更快的推进 C++ 的发展,使得这门古老而又新颖的语言更加充满活力。 23 | 24 | ## 目标读者 25 | 26 | 1. 本书假定读者已经熟悉了传统 C++ ,至少在阅读传统 C++ 代码上不具备任何困难。换句话说,那些长期使用传统 C++进行编码的人、渴望在短时间内迅速了解**现代 C++** 特性的人非常适合阅读本书; 27 | 2. 本书一定程度上介绍了一些现代 C++ 的**黑魔法**,但这些魔法毕竟有限,不适合希望进阶学习现代 C++ 的读者,本书的定位系**现代 C++ 的快速上手**。当然,希望进阶学习的读者可以使用本书来回顾并检验自己对 **现代 C++** 的熟悉度。 28 | 29 | ## 本书目的 30 | 31 | 本书号称『高速上手』,从内容上对二十一世纪二十年代之前产生 C++ 的相关特性做了非常相对全面的介绍,读者可以自行根据下面的目录选取感兴趣的内容进行学习,快速熟悉需要了解的内容。这些特性并不需要全部掌握,只需针对自己的使用需求和特定的应用场景,学习、查阅最适合自己的新特性即可。 32 | 33 | 同时,本书在介绍这些特性的过程中,尽可能简单明了的介绍了这些特性产生的历史背景和技术需求,这为理解这些特性、运用这些特性提供了很大的帮助。 34 | 35 | 此外,笔者希望读者在阅读本书后,能够努力在新项目中直接使用 C++17,并努力将旧项目逐步迁移到 C++17。也算是笔者为推进现代 C++ 的普及贡献了一些绵薄之力。 36 | 37 | ## 相关代码 38 | 39 | 本书每章中都出现了大量的代码,如果你在跟随本书介绍特性的思路编写自己的代码遇到问题时,不妨读一读随书附上的源码,你可以在[这里](../../code)中找到书中介绍过的全部的源码,所有代码按章节组织,文件夹名称为章节序号。 40 | 41 | ## 随书习题 42 | 43 | 本书每章最后还加入了少量难度极小的习题,仅用于检验你是否能混合运用当前章节中的知识点。你可以在[这里](../../exercises)找到习题的答案,文件夹名称为章节序号。 44 | 45 | [返回目录](./toc.md) | [下一章 迈向现代 C++](./01-intro.md) 46 | 47 | ## 许可 48 | 49 | 知识共享许可协议 50 | 51 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 52 | -------------------------------------------------------------------------------- /github_code/book/zh-cn/01-intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 第 1 章 迈向现代 C++ 3 | type: book-zh-cn 4 | order: 1 5 | --- 6 | 7 | # 第 1 章 迈向现代 C++ 8 | 9 | [TOC] 10 | 11 | **编译环境**:本书将使用 `clang++` 作为唯一使用的编译器,同时总是在代码中使用 `-std=c++2a` 编译标志。 12 | 13 | ```bash 14 | > clang++ -v 15 | Apple LLVM version 10.0.1 (clang-1001.0.46.4) 16 | Target: x86_64-apple-darwin18.6.0 17 | Thread model: posix 18 | InstalledDir: /Library/Developer/CommandLineTools/usr/bin 19 | ``` 20 | 21 | ## 1.1 被弃用的特性 22 | 23 | 在学习现代 C++ 之前,我们先了解一下从 C++11 开始,被弃用的主要特性: 24 | 25 | > **注意**:弃用并非彻底不能用,只是用于暗示程序员这些特性将从未来的标准中消失,应该尽量避免使用。但是,已弃用的特性依然是标准库的一部分,并且出于兼容性的考虑,大部分特性其实会『永久』保留。 26 | 27 | - **不再允许字符串字面值常量赋值给一个 `char *`。如果需要用字符串字面值常量赋值和初始化一个 `char *`,应该使用 `const char *` 或者 `auto`。** 28 | ```cpp 29 | char *str = "hello world!"; // 将出现弃用警告 30 | ``` 31 | 32 | - **C++98 异常说明、 `unexpected_handler`、`set_unexpected()` 等相关特性被弃用,应该使用 `noexcept`。** 33 | 34 | - **`auto_ptr` 被弃用,应使用 `unique_ptr`。** 35 | 36 | - **`register` 关键字被弃用,可以使用但不再具备任何实际含义。** 37 | 38 | - **`bool` 类型的 `++` 操作被弃用。** 39 | 40 | - **如果一个类有析构函数,为其生成拷贝构造函数和拷贝赋值运算符的特性被弃用了。** 41 | 42 | - **C 语言风格的类型转换被弃用(即在变量前使用 `(convert_type)`),应该使用 `static_cast`、`reinterpret_cast`、`const_cast` 来进行类型转换。** 43 | 44 | - **特别地,在最新的 C++17 标准中弃用了一些可以使用的 C 标准库,例如 ``、``、`` 与 `` 等** 45 | 46 | - ……等等 47 | 48 | 还有一些其他诸如参数绑定(C++11 提供了 `std::bind` 和 `std::function`)、`export` 等特性也均被弃用。前面提到的这些特性**如果你从未使用或者听说过,也请不要尝试去了解他们,应该向新标准靠拢**,直接学习新特性。毕竟,技术是向前发展的。 49 | 50 | ## 1.2 与 C 的兼容性 51 | 52 | 出于一些不可抗力、历史原因,我们不得不在 C++ 中使用一些 C 语言代码(甚至古老的 C 语言代码),例如 Linux 系统调用。在现代 C++ 出现之前,大部分人当谈及『C 与 C++ 的区别是什么』时,普遍除了回答面向对象的类特性、泛型编程的模板特性外,就没有其他的看法了,甚至直接回答『差不多』,也是大有人在。图 1.2 中的韦恩图大致上回答了 C 和 C++ 相关的兼容情况。 53 | 54 | ![图 1.2: C 和 C++ 互相兼容情况](../../assets/figures/comparison.png) 55 | 56 | 从现在开始,你的脑子里应该树立『**C++ 不是 C 的一个超集**』这个观念(而且从一开始就不是,后面的[进一步阅读的参考文献](#进一步阅读的参考文献)中给出了 C++98 和 C99 之间的区别)。在编写 C++ 时,也应该尽可能的避免使用诸如 `void*` 之类的程序风格。而在不得不使用 C 时,应该注意使用 `extern "C"` 这种特性,将 C 语言的代码与 C++代码进行分离编译,再统一链接这种做法,例如: 57 | 58 | ```cpp 59 | // foo.h 60 | #ifdef __cplusplus 61 | extern "C" { 62 | #endif 63 | 64 | int add(int x, int y); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | // foo.c 71 | int add(int x, int y) { 72 | return x+y; 73 | } 74 | 75 | // 1.1.cpp 76 | #include "foo.h" 77 | #include 78 | #include 79 | 80 | int main() { 81 | [out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){ 82 | out.get() << ".\n"; 83 | }(); 84 | return 0; 85 | } 86 | ``` 87 | 88 | 应先使用 `gcc` 编译 C 语言的代码: 89 | 90 | ```bash 91 | gcc -c foo.c 92 | ``` 93 | 94 | 编译出 `foo.o` 文件,再使用 `clang++` 将 C++代码和 `.o` 文件链接起来(或者都编译为 `.o` 再统一链接): 95 | 96 | ```bash 97 | clang++ 1.1.cpp foo.o -std=c++2a -o 1.1 98 | ``` 99 | 100 | 当然,你可以使用 `Makefile` 来编译上面的代码: 101 | 102 | ```makefile 103 | C = gcc 104 | CXX = clang++ 105 | 106 | SOURCE_C = foo.c 107 | OBJECTS_C = foo.o 108 | 109 | SOURCE_CXX = 1.1.cpp 110 | 111 | TARGET = 1.1 112 | LDFLAGS_COMMON = -std=c++2a 113 | 114 | all: 115 | $(C) -c $(SOURCE_C) 116 | $(CXX) $(SOURCE_CXX) $(OBJECTS_C) $(LDFLAGS_COMMON) -o $(TARGET) 117 | clean: 118 | rm -rf *.o $(TARGET) 119 | ``` 120 | 121 | > 注意:`Makefile` 中的缩进是制表符而不是空格符,如果你直接复制这段代码到你的编辑器中,制表符可能会被自动替换掉,请自行确保在 `Makefile` 中的缩进是由制表符完成的。 122 | > 123 | > 如果你还不知道 Makefile 的使用也没有关系,本教程中不会构建过于复杂的代码,简单的在命令行中使用 `clang++ -std=c++2a` 也可以阅读本书。 124 | 125 | 如果你是首次接触现代 C++,那么你很可能还看不懂上面的那一小段代码,即: 126 | 127 | ```cpp 128 | [out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){ 129 | out.get() << ".\n"; 130 | }(); 131 | ``` 132 | 133 | 不必担心,本书的后续章节将为你介绍这一切。 134 | 135 | [返回目录](./toc.md) | [上一章](./00-preface.md) | [下一章 语言可用性强化](./02-usability.md) 136 | 137 | ## 进一步阅读的参考文献 138 | 139 | - [C++ 语言导学. Bjarne Stroustrup](https://www.amazon.cn/dp/B00WUBYBYS/ref=sr_1_1?ie=UTF8&qid=1522400738&sr=8-1&keywords=C%2B%2B+%E8%AF%AD%E8%A8%80%E5%AF%BC%E5%AD%A6) 140 | - [C++ 历史](http://en.cppreference.com/w/cpp/language/history) 141 | - [C++ 特性在 GCC/Clang 等编译器中的支持情况](http://en.cppreference.com/w/cpp/compiler_support) 142 | - [C++98 与 C99 之间的区别](http://david.tribble.com/text/cdiffs.htm#C99-vs-CPP98) 143 | 144 | ## 许可 145 | 146 | 知识共享许可协议 147 | 148 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 149 | -------------------------------------------------------------------------------- /github_code/book/zh-cn/08-filesystem.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 第 8 章 文件系统 3 | type: book-zh-cn 4 | order: 8 5 | --- 6 | 7 | # 第 8 章 文件系统 8 | 9 | [TOC] 10 | 11 | 文件系统库提供了文件系统、路径、常规文件、目录等等相关组件进行操作的相关功能。和正则表达式库类似,他也是最先由 boost 发起,并最终被合并为 C++ 标准的众多库之一。 12 | 13 | ## 8.1 文档与链接 14 | 15 | TODO: 16 | 17 | ## 8.2 std::filesystem 18 | 19 | TODO: 20 | 21 | [返回目录](./toc.md) | [上一章](./07-thread.md) | [下一章 其他杂项](./09-others.md) 22 | 23 | ## 许可 24 | 25 | 知识共享许可协议 26 | 27 | 本教程由[欧长坤](https://github.com/changkun)撰写,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 28 | -------------------------------------------------------------------------------- /github_code/book/zh-cn/09-others.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 第 9 章 其他杂项 3 | type: book-zh-cn 4 | order: 9 5 | --- 6 | 7 | # 第 9 章 其他杂项 8 | 9 | [TOC] 10 | 11 | ## 9.1 新类型 12 | 13 | ### `long long int` 14 | 15 | `long long int` 并不是 C++11 最先引入的,其实早在 C99, 16 | `long long int` 就已经被纳入 C 标准中,所以大部分的编译器早已支持。 17 | C++11 的工作则是正式把它纳入标准库, 18 | 规定了一个 `long long int` 类型至少具备 64 位的比特数。 19 | 20 | ## 9.2 noexcept 的修饰和操作 21 | 22 | C++ 相比于 C 的一大优势就在于 C++ 本身就定义了一套完整的异常处理机制。 23 | 然而在 C++11 之前,几乎没有人去使用在函数名后书写异常声明表达式, 24 | 从 C++11 开始,这套机制被弃用,所以我们不去讨论也不去介绍以前这套机制是如何工作如何使用, 25 | 你更不应该主动去了解它。 26 | 27 | C++11 将异常的声明简化为以下两种情况: 28 | 29 | 1. 函数可能抛出任何异常 30 | 2. 函数不能抛出任何异常 31 | 32 | 并使用 `noexcept` 对这两种行为进行限制,例如: 33 | 34 | ```cpp 35 | void may_throw(); // 可能抛出异常 36 | void no_throw() noexcept; // 不可能抛出异常 37 | ``` 38 | 39 | 使用 `noexcept` 修饰过的函数如果抛出异常,编译器会使用 `std::terminate()` 来立即终止程序运行。 40 | 41 | `noexcept` 还能够做操作符,用于操作一个表达式,当表达式无异常时,返回 `true`,否则返回 `false`。 42 | 43 | ```cpp 44 | #include 45 | void may_throw() { 46 | throw true; 47 | } 48 | auto non_block_throw = []{ 49 | may_throw(); 50 | }; 51 | void no_throw() noexcept { 52 | return; 53 | } 54 | 55 | auto block_throw = []() noexcept { 56 | no_throw(); 57 | }; 58 | int main() 59 | { 60 | std::cout << std::boolalpha 61 | << "may_throw() noexcept? " << noexcept(may_throw()) << std::endl 62 | << "no_throw() noexcept? " << noexcept(no_throw()) << std::endl 63 | << "lmay_throw() noexcept? " << noexcept(non_block_throw()) << std::endl 64 | << "lno_throw() noexcept? " << noexcept(block_throw()) << std::endl; 65 | return 0; 66 | } 67 | ``` 68 | 69 | `noexcept` 修饰完一个函数之后能够起到封锁异常扩散的功效,如果内部产生异常,外部也不会触发。例如: 70 | 71 | ```cpp 72 | try { 73 | may_throw(); 74 | } catch (...) { 75 | std::cout << "捕获异常, 来自 my_throw()" << std::endl; 76 | } 77 | try { 78 | non_block_throw(); 79 | } catch (...) { 80 | std::cout << "捕获异常, 来自 non_block_throw()" << std::endl; 81 | } 82 | try { 83 | block_throw(); 84 | } catch (...) { 85 | std::cout << "捕获异常, 来自 block_throw()" << std::endl; 86 | } 87 | ``` 88 | 89 | 最终输出为: 90 | 91 | ``` 92 | 捕获异常, 来自 my_throw() 93 | 捕获异常, 来自 non_block_throw() 94 | ``` 95 | 96 | ## 9.3 字面量 97 | 98 | ### 原始字符串字面量 99 | 100 | 传统 C++ 里面要编写一个充满特殊字符的字符串其实是非常痛苦的一件事情, 101 | 比如一个包含 HTML 本体的字符串需要添加大量的转义符, 102 | 例如一个Windows 上的文件路径经常会:`C:\\File\\To\\Path`。 103 | 104 | C++11 提供了原始字符串字面量的写法,可以在一个字符串前方使用 `R` 来修饰这个字符串, 105 | 同时,将原始字符串使用括号包裹,例如: 106 | 107 | ```cpp 108 | #include 109 | #include 110 | 111 | int main() { 112 | std::string str = R"(C:\File\To\Path)"; 113 | std::cout << str << std::endl; 114 | return 0; 115 | } 116 | ``` 117 | 118 | ### 自定义字面量 119 | 120 | C++11 引进了自定义字面量的能力,通过重载双引号后缀运算符实现: 121 | 122 | ```cpp 123 | // 字符串字面量自定义必须设置如下的参数列表 124 | std::string operator"" _wow1(const char *wow1, size_t len) { 125 | return std::string(wow1)+"woooooooooow, amazing"; 126 | } 127 | 128 | std::string operator"" _wow2 (unsigned long long i) { 129 | return std::to_string(i)+"woooooooooow, amazing"; 130 | } 131 | 132 | int main() { 133 | auto str = "abc"_wow1; 134 | auto num = 1_wow2; 135 | std::cout << str << std::endl; 136 | std::cout << num << std::endl; 137 | return 0; 138 | } 139 | ``` 140 | 141 | 自定义字面量支持四种字面量: 142 | 143 | 1. 整型字面量:重载时必须使用 `unsigned long long`、`const char *`、模板字面量算符参数,在上面的代码中使用的是前者; 144 | 2. 浮点型字面量:重载时必须使用 `long double`、`const char *`、模板字面量算符; 145 | 3. 字符串字面量:必须使用 `(const char *, size_t)` 形式的参数表; 146 | 4. 字符字面量:参数只能是 `char`, `wchar_t`, `char16_t`, `char32_t` 这几种类型。 147 | 148 | ## 9.4 内存对齐 149 | 150 | C++ 11 引入了两个新的关键字 `alignof` 和 `alignas` 来支持对内存对齐进行控制。 151 | `alignof` 关键字能够获得一个与平台相关的 `std::size_t` 类型的值,用于查询该平台的对齐方式。 152 | 当然我们有时候并不满足于此,甚至希望自定定义结构的对齐方式,同样,C++ 11 还引入了 `alignas` 153 | 来重新修饰某个结构的对齐方式。我们来看两个例子: 154 | 155 | ```cpp 156 | #include 157 | 158 | struct Storage { 159 | char a; 160 | int b; 161 | double c; 162 | long long d; 163 | }; 164 | 165 | struct alignas(std::max_align_t) AlignasStorage { 166 | char a; 167 | int b; 168 | double c; 169 | long long d; 170 | }; 171 | 172 | int main() { 173 | std::cout << alignof(Storage) << std::endl; 174 | std::cout << alignof(AlignasStorage) << std::endl; 175 | return 0; 176 | } 177 | ``` 178 | 179 | 其中 `std::max_align_t` 要求每个标量类型的对齐方式严格一样,因此它几乎是最大标量没有差异, 180 | 进而大部分平台上得到的结果为 `long double`,因此我们这里得到的 `AlignasStorage` 的对齐要求是 8 或 16。 181 | 182 | ## 总结 183 | 184 | 本节介绍的几个特性是从仍未介绍的现代 C++ 新特性里使用频次较靠前的特性了,`noexcept` 是最为重要的特性,它的一个功能在于能够阻止异常的扩散传播,有效的让编译器最大限度的优化我们的代码。 185 | 186 | [返回目录](./toc.md) | [上一章](./08-filesystem.md) | [下一章 展望:C++20 简介](./10-cpp20.md) 187 | 188 | ## 许可 189 | 190 | 知识共享许可协议 191 | 192 | 本教程由[欧长坤](https://github.com/changkun)撰写,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 -------------------------------------------------------------------------------- /github_code/book/zh-cn/10-cpp20.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 第 10 章 展望:C++20 简介 3 | type: book-zh-cn 4 | order: 10 5 | --- 6 | 7 | # 第 10 章 展望:C++20 简介 8 | 9 | [TOC] 10 | 11 | C++20 如同 C++11 一样,似乎能够成为一个振奋人心的更新。例如,早在 C++11 时期就跃跃欲试呼声极高却最终落选的 `Concept`,如今已经箭在弦上。 12 | C++ 组委会在讨论投票最终确定 C++20 有很多提案,诸如 **Concepts**/**Module**/**Coroutine**/**Ranges**/ 等等。 13 | 本章我们就来一览 C++20 即将引入的那些重要特性。 14 | 15 | ## 概念与约束 16 | 17 | 概念(Concepts)是对 C++ 模板编程的进一步增强扩展。简单来说,概念是一种编译期的特性, 18 | 它能够让编译器在编译期时对模板参数进行判断,从而大幅度增强我们在 C++ 中模板编程的体验。 19 | 使用模板进行编程时候我们经常会遇到各种令人发指的错误, 20 | 这是因为到目前为止我们始终不能够对模板参数进行检查与限制。 21 | 举例而言,下面简单的两行代码会造成大量的几乎不可读的编译错误: 22 | 23 | ```cpp 24 | #include 25 | #include 26 | int main() { 27 | std::list l = {1, 2, 3}; 28 | std::sort(l.begin(), l.end()); 29 | return 0; 30 | } 31 | ``` 32 | 33 | 而这段代码出现错误的根本原因在于,`std::sort` 对排序容器必须提供随机迭代器,否则就不能使用,而我们知道 `std::list` 是不支持随机访问的。 34 | 用概念的语言来说就是:`std::list` 中的迭代器不满足 `std::sort` 中随机迭代器这个概念的约束(Constraint)。 35 | 在引入概念后,我们就可以这样对模板参数进行约束: 36 | 37 | ```cpp 38 | template 39 | requires Sortable // Sortable 是一个概念 40 | void sort(T& c); 41 | ``` 42 | 43 | 缩写为: 44 | 45 | ```cpp 46 | template // T 是一个 Sortable 的类型名 47 | void sort(T& c) 48 | ``` 49 | 50 | 甚至于直接将其作为类型来使用: 51 | 52 | ```cpp 53 | void sort(Sortable& c); // c 是一个 Sortable 类型的对象 54 | ``` 55 | 56 | 我们现在来看一个实际的例子。 57 | 58 | TODO: https://godbolt.org/z/9liFPD 59 | 60 | ## 模块 61 | 62 | TODO: 63 | 64 | ## 合约 65 | 66 | TODO: 67 | 68 | ## 范围 69 | 70 | TODO: 71 | 72 | ## 协程 73 | 74 | TODO: 75 | 76 | 77 | ## 事务内存 78 | 79 | TODO: 80 | 81 | ## 总结 82 | 83 | 总的来说,终于在 C++20 中看到 Concepts/Ranges/Modules 这些令人兴奋的特性, 84 | 这对于一门已经三十多岁『高龄』的编程语言,依然是充满魅力的。 85 | 86 | [返回目录](./toc.md) | [上一章](./09-others.md) | [下一章 进一步阅读的学习材料](./appendix1.md) 87 | 88 | 89 | ## 进一步阅读的参考资料 90 | 91 | - [Why Concepts didn't make C++17?](http://honermann.net/blog/2016/03/06/why-concepts-didnt-make-cxx17/) 92 | - [C++11/14/17/20 编译器支持情况](http://en.cppreference.com/w/cpp/compiler_support) 93 | - [C++ 历史](https://en.cppreference.com/w/cpp/language/history) 94 | 95 | ## 许可 96 | 97 | 知识共享许可协议 98 | 99 | 本教程由[欧长坤](https://github.com/changkun)撰写,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 -------------------------------------------------------------------------------- /github_code/book/zh-cn/appendix1.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 附录 1:进一步阅读的学习材料 3 | type: book-zh-cn 4 | order: 11 5 | --- 6 | 7 | # 附录 1:进一步阅读的学习材料 8 | 9 | 首先,恭喜 🎉 你阅读完本书!笔者希望本书有提起你对现代 C++ 的兴趣。 10 | 11 | 正如本书引言部分提到的,本书只是一本带你快速领略现代 C++ 11/14/17/20 新特性的读物,而非进阶学习实践 C++『黑魔法』的内容。笔者当然也想到了这个需求,只是这样的内容非常艰深,鲜有受众。在此,笔者列出一些能够帮助你在此书基础之上进一步学习现代 C++ 的资料,希望能够祝你一臂之力: 12 | 13 | - [C++ 参考](http://en.cppreference.com/w) 14 | - [CppCon YouTube 频道](https://www.youtube.com/user/CppCon/videos) 15 | - [Ulrich Drepper. 每位程序员都需要知道的内存知识. 2007](https://people.freebsd.org/~lstewart/articles/cpumemory.pdf) 16 | - 待补充 17 | 18 | [返回目录](./toc.md) | [上一章](./10-cpp20.md) | [下一章 现代 C++ 的最佳实践](./appendix2.md) 19 | 20 | ## 许可 21 | 22 | 知识共享许可协议 23 | 24 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 -------------------------------------------------------------------------------- /github_code/book/zh-cn/appendix2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 附录 2:现代 C++ 的最佳实践 3 | type: book-zh-cn 4 | order: 12 5 | --- 6 | 7 | # 附录 2:现代 C++ 的最佳实践 8 | 9 | 这篇附录我们来简单谈一谈现代 C++ 的最佳实践。总的来说,笔者关于 C++ 的最佳实践相关的思考主要吸收自[《Effective Modern C++》](https://www.amazon.cn/dp/B016OFO492/ref=sr_1_3?ie=UTF8&qid=1525613457&sr=8-3&keywords=Effective+C%2B%2B)和 [《C++ 风格指南》](http://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/)。在这篇附录里将简单讨论、并使用实际例子来阐明的方法,介绍一些笔者**个人的**、**不是随处可见的**、**非常识性**的最佳实践,并如何保证代码的整体质量。 10 | 11 | ## 常用工具 12 | 13 | TODO: 14 | 15 | ## 代码风格 16 | 17 | TODO: 18 | 19 | ## 整体性能 20 | 21 | TODO: 22 | 23 | ## 代码安全 24 | 25 | TODO: 26 | 27 | ## 可维护性 28 | 29 | TODO: 30 | 31 | ## 可移植性 32 | 33 | TODO: 34 | 35 | [返回目录](./toc.md) | [上一章](./11-appendix1.md) 36 | 37 | ## 许可 38 | 39 | 知识共享许可协议 40 | 41 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 -------------------------------------------------------------------------------- /github_code/book/zh-cn/appendix3.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 附录 3:现代 C++ 特性索引 3 | type: book-zh-cn 4 | order: 13 5 | --- 6 | 7 | # 附录 3:现代 C++ 特性索引表 8 | 9 | | 特性概述 | 首次出现章节 | 首次出现版本 | 10 | |:--------|:-----------|:----------| 11 | | 概念(Concept) | 第二章 | C++20 | 12 | | 模板参数推导 | | C++17 | 13 | | 非类型模板参数的 auto 推导 | | C++17 | 14 | | 折叠表达式 | | C++17 | 15 | | 花括号初始化列表的 auto 推导 | | C++17 | 16 | | constexpr lambda | | C++17 | 17 | | lambda 表达式的 this 值捕获 | | C++17 | 18 | | 内联变量 | | C++17 | 19 | | 嵌套 namespace | | C++17 | 20 | | 结构化绑定 | | C++17 | 21 | | 带初始值的 switch 语句 | | C++17 | 22 | | constexpr if | | C++17 | 23 | | UTF-8 字符字面量 | | C++17 | 24 | | 枚举的直接初始化列表 | | C++17 | 25 | | attributes | | C++17 | 26 | | `std::variant` | | C++17 | 27 | | `std::optional` | | C++17 | 28 | | `std::any` | | C++17 | 29 | | `std::string_view` | | C++17 | 30 | | `std::invoke` | | C++17 | 31 | | `std::apply` | | C++17 | 32 | | `std::filesystem` | | C++17 | 33 | | `std::byte` | | C++17 | 34 | | map 和 set 的拼接 | | C++17 | 35 | | 并行算法 | | C++17 | 36 | 37 | -------------------------------------------------------------------------------- /github_code/book/zh-cn/toc.md: -------------------------------------------------------------------------------- 1 | # 现代 C++ 教程:高速上手 C++ 11/14/17/20 2 | 3 | ## 目录 4 | 5 | - [**序言**](./00-preface.md) 6 | - [**第 1 章 迈向现代 C++**](./01-intro.md) 7 | + 1.1 被弃用的特性 8 | + 1.2 与 C 的兼容性 9 | + 进一步阅读的参考文献 10 | - [**第 2 章 语言可用性的强化**](./02-usability.md) 11 | + 2.1 常量 12 | - nullptr 13 | - constexpr 14 | + 2.2 变量及其初始化 15 | - if/switch 变量声明强化 16 | - 初始化列表 17 | - 结构化绑定 18 | + 2.3 类型推导 19 | - auto 20 | - decltype 21 | - 尾返回类型 22 | - decltype(auto) 23 | + 2.4 控制流 24 | - if constexpr 25 | - 区间 for 迭代 26 | + 2.5 模板 27 | - 外部模板 28 | - 尖括号 ">" 29 | - 类型别名模板 30 | - 默认模板参数 31 | - 变长参数模板 32 | - 折叠表达式 33 | - 非类型模板参数推导 34 | + 2.6 面向对象 35 | - 委托构造 36 | - 继承构造 37 | - 显式虚函数重载 38 | - override 39 | - final 40 | - 显式禁用默认函数 41 | - 强类型枚举 42 | - [**第 3 章 语言运行期的强化**](./03-runtime.md) 43 | + 3.1 lambda 表达式 44 | + 基础 45 | + 泛型 46 | + 3.2 函数对象包装器 47 | + std::function 48 | + std::bind 和 std::placeholder 49 | + 3.3 右值引用 50 | + 左值、右值的纯右值、将亡值、右值 51 | + 右值引用和左值引用 52 | + 移动语义 53 | + 完美转发 54 | - [**第 4 章 标准库: 容器**](./04-containers.md) 55 | + 4.1 线性容器 56 | + `std::array` 57 | + `std::forward_list` 58 | + 4.2 无序容器 59 | + `std::unordered_set` 60 | + `std::unordered_map` 61 | + 4.3 元组 `std::tuple` 62 | + 基本操作 63 | + 运行期索引 `std::variant` 64 | + 合并与迭代 65 | - [**第 5 章 标准库: 指针**](./05-pointers.md) 66 | + 5.1 RAII 与引用计数 67 | + 5.2 `std::shared_ptr` 68 | + 5.3 `std::unique_ptr` 69 | + 5.4 `std::weak_ptr` 70 | - [**第 6 章 标准库: 正则表达式**](./06-regex.md) 71 | + 6.1 正则表达式简介 72 | + 普通字符 73 | + 特殊字符 74 | + 限定符 75 | + 6.2 `std::regex` 及其相关 76 | + `std::regex` 77 | + `std::regex_match` 78 | + `std::match_results` 79 | - [**第 7 章 并行与并发**](./07-thread.md) 80 | + 7.1 并行基础 81 | + 7.2 互斥量与临界区 82 | + 7.3 期物 83 | + 7.4 条件变量 84 | + 7.5 原子操作与内存模型 85 | + 原子操作 86 | + 一致性模型 87 | + 内存顺序 88 | - [**第 8 章 文件系统**](./08-filesystem.md) 89 | + 8.1 文档与链接 90 | + 8.2 `std::filesystem` 91 | - [**第 9 章 其他杂项**](./09-others.md) 92 | + 9.1 新类型 93 | + `long long int` 94 | + 9.2 `noexcept` 的修饰和操作 95 | + 9.3 字面量 96 | + 原始字符串字面量 97 | + 自定义字面量 98 | + 9.4 内存对齐 99 | - [**第 10 章 展望: C++20 简介**](./10-cpp20.md) 100 | + 10.1 Concept 101 | + 10.2 Range 102 | + 10.3 Module 103 | + 10.4 Coroutine 104 | + 10.5 事务内存 105 | - [**附录 1:进一步阅读的学习材料**](./appendix1.md) 106 | - [**附录 2:现代 C++ 的最佳实践**](./appendix2.md) 107 | 108 | 返回目录 | 上一章 | [下一章:序言](./00-preface.md) 109 | 110 | ## 许可 111 | 112 | 知识共享许可协议 113 | 114 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 MIT 协议开源,参见[许可](../../LICENSE)。 115 | -------------------------------------------------------------------------------- /github_code/code/1/1.1.c.and.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 1.1.cpp 3 | // 4 | // chapter 1 introduction 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial 9 | // 10 | 11 | #include "foo.h" 12 | #include 13 | #include 14 | 15 | int main() { 16 | // use lambda expression 17 | [out = std::ref(std::cout << "Result from C code: " << add(1, 2))](){ 18 | out.get() << ".\n"; 19 | }(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /github_code/code/1/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # 1.1.cpp 3 | # 4 | # chapter 1 introduction 5 | # modern cpp tutorial 6 | # 7 | # created by changkun at changkun.de 8 | # https://github.com/changkun/modern-cpp-tutorial 9 | # 10 | 11 | C = gcc 12 | CXX = clang++ 13 | 14 | SOURCE_C = foo.c 15 | OBJECTS_C = foo.o 16 | 17 | SOURCE_CXX = 1.1.c.and.cpp 18 | 19 | TARGET = 1.1.out 20 | LDFLAGS_COMMON = -std=c++2a 21 | 22 | all: 23 | $(C) -c $(SOURCE_C) 24 | $(CXX) $(SOURCE_CXX) $(OBJECTS_C) $(LDFLAGS_COMMON) -o $(TARGET) 25 | clean: 26 | rm -rf *.o $(TARGET) 27 | -------------------------------------------------------------------------------- /github_code/code/1/foo.c: -------------------------------------------------------------------------------- 1 | // 2 | // foo.c 3 | // 4 | // chapter 1 introduction 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial 9 | // 10 | 11 | #include "foo.h" 12 | 13 | // C code 14 | int add(int x, int y) { 15 | return x+y; 16 | } 17 | -------------------------------------------------------------------------------- /github_code/code/1/foo.h: -------------------------------------------------------------------------------- 1 | // 2 | // foo.h 3 | // 4 | // chapter 1 introduction 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial 9 | // 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | int add(int x, int y); 16 | 17 | #ifdef __cplusplus 18 | } 19 | #endif 20 | -------------------------------------------------------------------------------- /github_code/code/10/10.1.without.concepts.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 10.1.without.concepts.cpp 3 | // chapter 10 cpp20 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | #include 13 | 14 | int main() { 15 | std::list l = {1, 2, 3}; 16 | // std::sort(l.begin(), l.end()); // tons of compile error 17 | return 0; 18 | } -------------------------------------------------------------------------------- /github_code/code/10/10.2.concepts.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 10.2.concepts.cpp 3 | // chapter 10 cpp20 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | 18 | template 19 | concept bool Stringable = requires(T a){ 20 | {a.to_string()} -> string; 21 | }; 22 | 23 | template 24 | concept bool HasStringFunc = requires(T a){ 25 | { to_string(a) } -> string; 26 | }; 27 | 28 | struct Person { 29 | double height, weight; 30 | Person(double a, double b) : height(a), weight(b) {} 31 | string to_string(){ 32 | return "weight: "+ std::to_string(weight) + ", height: "+ std::to_string(height); 33 | } 34 | }; 35 | 36 | 37 | namespace std { 38 | 39 | string to_string(list l){ 40 | string s = ""; 41 | for(int a : l ){ 42 | s+=(" " + to_string(a) + " "); 43 | } 44 | return s; 45 | } 46 | 47 | } 48 | 49 | string to_string(std::vector v){ 50 | string s = ""; 51 | for(int a : v ){ 52 | s += (" " + to_string(a) + " "); 53 | } 54 | return s; 55 | } 56 | 57 | 58 | void print(Stringable a){ 59 | std::cout << a.to_string() << std::endl; 60 | } 61 | 62 | void print(HasStringFunc a){ 63 | std::cout << to_string(a) << std::endl; 64 | } 65 | 66 | int main() { 67 | std::list l {1, 2, 3}; 68 | Person p(57, 170.0); 69 | std::vector v { 34, 23, 34, 56, 78}; 70 | 71 | print(p); // uses concept Stringable 72 | print(l); 73 | print(3); // uses concept HasStringFunc 74 | // print(v); // error 75 | return 0; 76 | } -------------------------------------------------------------------------------- /github_code/code/10/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/2/2.01.nullptr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.1.nullptr.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | void foo(char *); 14 | void foo(int); 15 | 16 | int main() { 17 | if (std::is_same::value) 18 | std::cout << "NULL == 0" << std::endl; 19 | if (std::is_same::value) 20 | std::cout << "NULL == (void *)0" << std::endl; 21 | if (std::is_same::value) 22 | std::cout << "NULL == nullptr" << std::endl; 23 | 24 | foo(0); // will call foo(int) 25 | // foo(NULL); // doesn't compile 26 | foo(nullptr); // will call foo(char*) 27 | return 0; 28 | } 29 | 30 | void foo(char *) { 31 | std::cout << "foo(char*) is called" << std::endl; 32 | } 33 | void foo(int i) { 34 | std::cout << "foo(int) is called" << std::endl; 35 | } 36 | -------------------------------------------------------------------------------- /github_code/code/2/2.02.constexpr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.2.constexpr.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #define LEN 10 12 | 13 | int len_foo() { 14 | int i = 2; 15 | return i; 16 | } 17 | constexpr int len_foo_constexpr() { 18 | return 5; 19 | } 20 | 21 | // error in c++11 22 | // constexpr int fibonacci(const int n) { 23 | // if(n == 1) return 1; 24 | // if(n == 2) return 1; 25 | // return fibonacci(n-1) + fibonacci(n-2); 26 | // } 27 | 28 | // ok 29 | constexpr int fibonacci(const int n) { 30 | return n == 1 || n == 2 ? 1 : fibonacci(n-1) + fibonacci(n-2); 31 | } 32 | 33 | 34 | int main() { 35 | char arr_1[10]; // legal 36 | char arr_2[LEN]; // legal 37 | 38 | int len = 10; 39 | // char arr_3[len]; // illegal 40 | 41 | const int len_2 = len + 1; 42 | constexpr int len_2_constexpr = 1 + 2 + 3; 43 | // char arr_4[len_2]; // illegal, but ok for most of the compilers 44 | char arr_4[len_2_constexpr]; // legal 45 | 46 | // char arr_5[len_foo()+5]; // illegal 47 | char arr_6[len_foo_constexpr() + 1]; // legal 48 | 49 | // 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 50 | std::cout << fibonacci(10) << std::endl; 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /github_code/code/2/2.03.if.switch.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.3.if.switch.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int main() { 15 | std::vector vec = {1, 2, 3, 4}; 16 | 17 | // after c++17, can be simplefied by using `auto` 18 | const std::vector::iterator itr = std::find(vec.begin(), vec.end(), 2); 19 | if (itr != vec.end()) { 20 | *itr = 3; 21 | } 22 | 23 | if (const std::vector::iterator itr = std::find(vec.begin(), vec.end(), 3); 24 | itr != vec.end()) { 25 | *itr = 4; 26 | } 27 | 28 | // should output: 1, 4, 3, 4. can be simplefied using `auto` 29 | for (std::vector::iterator element = vec.begin(); element != vec.end(); ++element) 30 | std::cout << *element << std::endl; 31 | } -------------------------------------------------------------------------------- /github_code/code/2/2.04.initializer.list.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.4.initializer.list.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | class Foo { 15 | public: 16 | int value_a; 17 | int value_b; 18 | Foo(int a, int b) : value_a(a), value_b(b) {} 19 | }; 20 | 21 | class MagicFoo { 22 | public: 23 | std::vector vec; 24 | MagicFoo(std::initializer_list list) { 25 | for (std::initializer_list::iterator it = list.begin(); it != list.end(); ++it) { 26 | vec.push_back(*it); 27 | } 28 | } 29 | void foo(std::initializer_list list) { 30 | for (std::initializer_list::iterator it = list.begin(); it != list.end(); ++it) { 31 | vec.push_back(*it); 32 | } 33 | } 34 | }; 35 | 36 | int main() { 37 | // before C++11 38 | int arr[3] = {1, 2, 3}; 39 | Foo foo(1, 2); 40 | std::vector vec = {1, 2, 3, 4, 5}; 41 | 42 | // after C++11 43 | MagicFoo magicFoo = {1, 2, 3, 4, 5}; 44 | magicFoo.foo({6,7,8,9}); 45 | Foo foo2 {3, 4}; 46 | 47 | std::cout << "arr[0]: " << arr[0] << std::endl; 48 | std::cout << "foo:" << foo.value_a << ", " << foo.value_b << std::endl; 49 | std::cout << "vec: "; 50 | for (std::vector::iterator it = vec.begin(); it != vec.end(); ++it) { 51 | std::cout << *it << std::endl; 52 | } 53 | std::cout << "magicFoo: "; 54 | for (std::vector::iterator it = magicFoo.vec.begin(); it != magicFoo.vec.end(); ++it) { 55 | std::cout << *it << std::endl; 56 | } 57 | std::cout << "foo2: " << foo2.value_a << ", " << foo2.value_b << std::endl; 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /github_code/code/2/2.05.structured.binding.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.5.structured.binding.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | std::tuple f() { 15 | return std::make_tuple(1, 2.3, "456"); 16 | } 17 | 18 | int main() { 19 | auto [x, y, z] = f(); 20 | std::cout << x << ", " << y << ", " << z << std::endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /github_code/code/2/2.06.auto.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.6.auto.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | class MagicFoo { 15 | public: 16 | std::vector vec; 17 | MagicFoo(std::initializer_list list) { 18 | for (auto it = list.begin(); it != list.end(); ++it) { 19 | vec.push_back(*it); 20 | } 21 | } 22 | }; 23 | 24 | // wrong 25 | // int add(auto x, auto y) { 26 | // return x+y; 27 | // } 28 | 29 | int main() { 30 | MagicFoo magicFoo = {1, 2, 3, 4, 5}; 31 | std::cout << "magicFoo: "; 32 | for (auto it = magicFoo.vec.begin(); it != magicFoo.vec.end(); ++it) { 33 | std::cout << *it << ", "; 34 | } 35 | std::cout << std::endl; 36 | 37 | auto i = 5; // type int 38 | auto j = 6; // type int 39 | auto arr = new auto(10); // type int* 40 | // auto auto_arr2[10] = {arr}; 41 | // std::cout << add(i, j) << std::endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /github_code/code/2/2.07.decltype.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.7.decltype.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | int main() { 14 | auto x = 1; 15 | auto y = 2; 16 | decltype(x+y) z = 3; 17 | if (std::is_same::value) 18 | std::cout << "type x == int" << std::endl; 19 | if (std::is_same::value) 20 | std::cout << "type z == float" << std::endl; 21 | if (std::is_same::value) 22 | std::cout << "type z == type x" << std::endl; 23 | return 0; 24 | } -------------------------------------------------------------------------------- /github_code/code/2/2.08.tail.return.type.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.8.tail.return.type.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | // before c++11 14 | template 15 | R add(T x, U y) { 16 | return x + y; 17 | } 18 | // after c++11 19 | template 20 | auto add2(T x, U y) -> decltype(x+y){ 21 | return x + y; 22 | } 23 | // after c++14 24 | template 25 | auto add3(T x, U y){ 26 | return x + y; 27 | } 28 | 29 | int main() { 30 | 31 | // before c++11 32 | int z = add(1, 2); 33 | std::cout << z << std::endl; 34 | 35 | // after c++11 36 | auto w = add2(1, 2.0); 37 | if (std::is_same::value) { 38 | std::cout << "w is double: "; 39 | } 40 | std::cout << w << std::endl; 41 | 42 | // after c++14 43 | auto q = add3(1.0, 2); 44 | std::cout << "q: " << q << std::endl; 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /github_code/code/2/2.09.decltype.auto.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.9.decltype.auto.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | template 11 | struct Int {}; 12 | 13 | constexpr auto iter(Int<0>) -> Int<0>; 14 | 15 | template 16 | constexpr auto iter(Int) { 17 | return iter(Int{}); 18 | } 19 | 20 | int main() { 21 | decltype(iter(Int<10>{})) a; 22 | } -------------------------------------------------------------------------------- /github_code/code/2/2.10.if.constexpr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.10.if.constexpr.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | 12 | template 13 | auto print_type_info(const T& t) { 14 | if constexpr (std::is_integral::value) { 15 | return t + 1; 16 | } else { 17 | return t + 0.001; 18 | } 19 | } 20 | 21 | // at compiling time 22 | // int print_type_info(const int& t) { 23 | // return t + 1; 24 | // } 25 | // double print_type_info(const double& t) { 26 | // return t + 0.001; 27 | // } 28 | 29 | int main() { 30 | std::cout << print_type_info(5) << std::endl; 31 | std::cout << print_type_info(3.14) << std::endl; 32 | } -------------------------------------------------------------------------------- /github_code/code/2/2.11.for.loop.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.11.for.loop.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int main() { 15 | std::vector vec = {1, 2, 3, 4}; 16 | if (auto itr = std::find(vec.begin(), vec.end(), 3); itr != vec.end()) *itr = 4; 17 | for (auto element : vec) 18 | std::cout << element << std::endl; // read only 19 | for (auto &element : vec) { 20 | element += 1; // writeable 21 | } 22 | for (auto element : vec) 23 | std::cout << element << std::endl; // read only 24 | } -------------------------------------------------------------------------------- /github_code/code/2/2.12.external.template.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.12.external.template.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | template class std::vector; // forcely instantiation 14 | extern template class std::vector; // external template for avoiding instantiation in this file 15 | 16 | template class MagicType { 17 | bool magic = T; 18 | }; 19 | 20 | int main() { 21 | // the >> in template 22 | std::vector> matrix; 23 | std::vector2)>> magic; // legal, but not recommended 24 | } -------------------------------------------------------------------------------- /github_code/code/2/2.13.alias.template.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.13.alias.template.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | template 15 | class MagicType { 16 | public: 17 | T dark; 18 | U magic; 19 | }; 20 | 21 | // illegal 22 | // template 23 | // typedef MagicType, std::string> FakeDarkMagic; 24 | 25 | typedef int (*process)(void *); 26 | using NewProcess = int(*)(void *); 27 | template 28 | using TrueDarkMagic = MagicType, std::string>; 29 | 30 | int main() { 31 | // FakeDarkMagic me; 32 | TrueDarkMagic you; 33 | } -------------------------------------------------------------------------------- /github_code/code/2/2.14.default.template.param.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.4.default.template.param.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | 12 | template 13 | auto add(T x, U y) -> decltype(x+y) { 14 | return x+y; 15 | } 16 | 17 | int main() { 18 | std::cout << add(1, 2) << std::endl; 19 | } -------------------------------------------------------------------------------- /github_code/code/2/2.15.variadic.template.param.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.15.variadic.template.param.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | // sizeof... 15 | template 16 | void magic(Ts... args) { 17 | std::cout << sizeof...(args) << std::endl; 18 | } 19 | 20 | 21 | // 1. recursive parameter unpack 22 | template 23 | void printf1(T0 value) { 24 | std::cout << value << std::endl; 25 | } 26 | template 27 | void printf1(T value, Ts... args) { 28 | std::cout << value << std::endl; 29 | printf1(args...); 30 | } 31 | 32 | // 2. variadic template parameter unfold 33 | template 34 | void printf2(T0 t0, T... t) { 35 | std::cout << t0 << std::endl; 36 | if constexpr (sizeof...(t) > 0) printf2(t...); 37 | } 38 | 39 | // 3. parameter unpack using initializer_list 40 | template 41 | auto printf3(T value, Ts... args) { 42 | std::cout << value << std::endl; 43 | (void) std::initializer_list{([&args] { 44 | std::cout << args << std::endl; 45 | }(), value)...}; 46 | } 47 | 48 | int main() { 49 | magic(); 50 | magic(1); 51 | magic(1,""); 52 | 53 | printf1(1, 2, "123", 1.1); 54 | printf2(1, 2.3, "abc"); 55 | printf3(111, 123, "alpha", 1.2); 56 | return 0; 57 | } -------------------------------------------------------------------------------- /github_code/code/2/2.16.fold.expression.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.16.fold.expression.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | template 12 | auto sum(T ... t) { 13 | return (t + ...); 14 | } 15 | int main() { 16 | std::cout << sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << std::endl; 17 | } -------------------------------------------------------------------------------- /github_code/code/2/2.18.non.type.template.auto.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.18.non.type.template.auto.cpp 3 | // chapter 2 language usability 4 | // modern cpp tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | 12 | template void foo() { 13 | std::cout << value << std::endl; 14 | return; 15 | } 16 | 17 | int main() { 18 | foo<10>(); // value is deduced as type int 19 | } -------------------------------------------------------------------------------- /github_code/code/2/2.19.delegate.constructor.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.19.constructor.cpp 3 | // chapter 2 language usability 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | class Base { 13 | public: 14 | std::string str; 15 | int value; 16 | Base() = delete; 17 | Base(std::string s) { 18 | str = s; 19 | } 20 | 21 | // delegate constructor 22 | Base(std::string s, int v) : Base(s) { 23 | value = v; 24 | } 25 | 26 | // final constructor 27 | virtual void foo() final { 28 | return; 29 | } 30 | virtual void foo(int v) { 31 | value = v; 32 | } 33 | }; 34 | class Subclass final : public Base { 35 | public: 36 | double floating; 37 | Subclass() = delete; 38 | 39 | // inherit constructor 40 | Subclass(double f, int v, std::string s) : Base(s, v) { 41 | floating = f; 42 | } 43 | 44 | // explifict constructor 45 | virtual void foo(int v) override { 46 | std::cout << v << std::endl; 47 | value = v; 48 | } 49 | }; // legal final 50 | 51 | // class Subclass2 : Subclass { 52 | // }; // illegal, Subclass has final 53 | // class Subclass3 : Base { 54 | // void foo(); // illegal, foo has final 55 | // } 56 | 57 | int main() { 58 | // Subclass oops; // illegal, default constructor has deleted 59 | Subclass s(1.2, 3, "abc"); 60 | 61 | s.foo(1); 62 | 63 | std::cout << s.floating << std::endl; 64 | std::cout << s.value << std::endl; 65 | std::cout << s.str << std::endl; 66 | } 67 | -------------------------------------------------------------------------------- /github_code/code/2/2.20.strong.type.enum.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 2.20.strong.type.enum.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include 10 | template 11 | std::ostream& operator<<(typename std::enable_if::value, std::ostream>::type& stream, const T& e) 12 | { 13 | return stream << static_cast::type>(e); 14 | } 15 | 16 | // there will be compile error if all define value1 和 value2 17 | enum Left { 18 | left_value1 = 1, 19 | left_value2 20 | }; 21 | enum Right { 22 | right_value1 = 1, 23 | right_value2 24 | }; 25 | 26 | enum class new_enum : unsigned int{ 27 | value1, 28 | value2, 29 | value3 = 100, 30 | value4 = 100 31 | }; 32 | 33 | int main() { 34 | 35 | if (Left::left_value1 == Right::right_value2) { 36 | std::cout << "Left::value1 == Right::value2" << std::endl; 37 | } 38 | 39 | // compile error 40 | // if(new_enum::left_value1 == 1) { 41 | // std::cout << "true!" << std::endl; 42 | // } 43 | if (new_enum::value3 == new_enum::value4) { 44 | std::cout << "new_enum::value3 == new_enum::value4" << std::endl; 45 | } 46 | 47 | std::cout << new_enum::value3 << std::endl; 48 | 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /github_code/code/2/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/3/3.1.lambda.basic.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.1.lambda.basic.cpp 3 | // chapter 03 runtime enhancement 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | #include 13 | 14 | void lambda_value_capture() { 15 | int value = 1; 16 | auto copy_value = [value] { 17 | return value; 18 | }; 19 | value = 100; 20 | auto stored_value = copy_value(); 21 | std::cout << "stored_value = " << stored_value << std::endl; 22 | // At this moment, stored_value == 1, and value == 100. 23 | // Because copy_value has copied when its was created. 24 | } 25 | 26 | void lambda_reference_capture() { 27 | int value = 1; 28 | auto copy_value = [&value] { 29 | return value; 30 | }; 31 | value = 100; 32 | auto stored_value = copy_value(); 33 | std::cout << "stored_value = " << stored_value << std::endl; 34 | // At this moment, stored_value == 100, value == 100. 35 | // Because copy_value stores reference 36 | } 37 | 38 | void lambda_expression_capture() { 39 | auto important = std::make_unique(1); 40 | auto add = [v1 = 1, v2 = std::move(important)](int x, int y) -> int { 41 | return x+y+v1+(*v2); 42 | }; 43 | std::cout << add(3,4) << std::endl; 44 | } 45 | 46 | void lambda_generic() { 47 | auto generic = [](auto x, auto y) { 48 | return x+y; 49 | }; 50 | 51 | std::cout << generic(1, 2) << std::endl; 52 | std::cout << generic(1.1, 2.2) << std::endl; 53 | } 54 | 55 | int main() { 56 | lambda_value_capture(); 57 | lambda_reference_capture(); 58 | lambda_expression_capture(); 59 | lambda_generic(); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /github_code/code/3/3.2.function.wrap.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.2.function.wrap.cpp 3 | // chapter 03 runtime enhancement 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | using foo = void(int); // function pointer 14 | void functional(foo f) { 15 | f(1); 16 | } 17 | 18 | int foo2(int para) { 19 | return para; 20 | } 21 | 22 | int foo3(int a, int b, int c) { 23 | return 0; 24 | } 25 | 26 | int main() { 27 | 28 | auto f = [](int value) { 29 | std::cout << value << std::endl; 30 | }; 31 | functional(f); // call by function pointer 32 | f(1); // call by lambda expression 33 | 34 | // std::function wraps a function that take int paremeter and returns int value 35 | std::function func = foo2; 36 | 37 | int important = 10; 38 | std::function func2 = [&](int value) -> int { 39 | return 1+value+important; 40 | }; 41 | std::cout << func(10) << std::endl; 42 | std::cout << func2(10) << std::endl; 43 | 44 | // bind parameter 1, 2 on function foo, and use std::placeholders::_1 as placeholder 45 | // for the first parameter. 46 | auto bindFoo = std::bind(foo3, std::placeholders::_1, 1,2); 47 | // when call bindFoo, we only need one param left 48 | bindFoo(1); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /github_code/code/3/3.3.rvalue.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.3.rvalue.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | 10 | #include 11 | #include 12 | 13 | void reference(std::string& str) { 14 | std::cout << "lvalue" << std::endl; 15 | } 16 | void reference(std::string&& str) { 17 | std::cout << "rvalue" << std::endl; 18 | } 19 | 20 | int main() 21 | { 22 | std::string lv1 = "string,"; // lv1 is a lvalue 23 | // std::string&& r1 = s1; // illegal, rvalue can't ref to lvalue 24 | std::string&& rv1 = std::move(lv1); // legal, std::move can convert lvalue to rvalue 25 | std::cout << rv1 << std::endl; // string, 26 | 27 | const std::string& lv2 = lv1 + lv1; // legal, const lvalue reference can extend temp variable's lifecycle 28 | // lv2 += "Test"; // illegal, const ref can't be modified 29 | std::cout << lv2 << std::endl; // string,string 30 | 31 | std::string&& rv2 = lv1 + lv2; // legal, rvalue ref extend lifecycle 32 | rv2 += "string"; // legal, non-const reference can be modified 33 | std::cout << rv2 << std::endl; // string,string,string, 34 | 35 | reference(rv2); // output: lvalue 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /github_code/code/3/3.4.historical.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.4.historical.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include 10 | 11 | int main() { 12 | // int &a = std::move(1); // illegal, non-const lvalue reference cannot ref rvalue 13 | const int &b = std::move(1); // legal, const lvalue reference can 14 | 15 | std::cout << b << std::endl; 16 | } -------------------------------------------------------------------------------- /github_code/code/3/3.5.move.semantics.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.5.move.semantics.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include 10 | class A { 11 | public: 12 | int *pointer; 13 | A():pointer(new int(1)) { 14 | std::cout << "construct" << pointer << std::endl; 15 | } 16 | A(A& a):pointer(new int(*a.pointer)) { 17 | std::cout << "copy" << pointer << std::endl; 18 | } // meaningless object copy 19 | A(A&& a):pointer(a.pointer) { 20 | a.pointer = nullptr; 21 | std::cout << "move" << pointer << std::endl; 22 | } 23 | ~A(){ 24 | std::cout << "destruct" << pointer << std::endl; 25 | delete pointer; 26 | } 27 | }; 28 | // avoid compiler optimization 29 | A return_rvalue(bool test) { 30 | A a,b; 31 | if(test) return a; // equal to static_cast(a); 32 | else return b; // equal to static_cast(b); 33 | } 34 | int main() { 35 | A obj = return_rvalue(false); 36 | std::cout << "obj:" << std::endl; 37 | std::cout << obj.pointer << std::endl; 38 | std::cout << *obj.pointer << std::endl; 39 | return 0; 40 | } -------------------------------------------------------------------------------- /github_code/code/3/3.6.move.semantics.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.5.move.semantics.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include // std::cout 10 | #include // std::move 11 | #include // std::vector 12 | #include // std::string 13 | 14 | int main() { 15 | 16 | std::string str = "Hello world."; 17 | std::vector v; 18 | 19 | // use push_back(const T&), copy 20 | v.push_back(str); 21 | // "str: Hello world." 22 | std::cout << "str: " << str << std::endl; 23 | 24 | // use push_back(const T&&), no copy 25 | // the string will be moved to vector, and therefore std::move can reduce copy cost 26 | v.push_back(std::move(str)); 27 | // str is empty now 28 | std::cout << "str: " << str << std::endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /github_code/code/3/3.7.perfect.forward.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 3.6.perfect.forward.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include 10 | #include 11 | void reference(int& v) { 12 | std::cout << "lvalue reference" << std::endl; 13 | } 14 | void reference(int&& v) { 15 | std::cout << "rvalue reference" << std::endl; 16 | } 17 | template 18 | void pass(T&& v) { 19 | std::cout << " normal param passing: "; 20 | reference(v); 21 | std::cout << " std::move param passing: "; 22 | reference(std::move(v)); 23 | std::cout << " std::forward param passing: "; 24 | reference(std::forward(v)); 25 | std::cout << "static_cast param passing: "; 26 | reference(static_cast(v)); 27 | } 28 | int main() { 29 | std::cout << "rvalue pass:" << std::endl; 30 | pass(1); 31 | 32 | std::cout << "lvalue pass:" << std::endl; 33 | int l = 1; 34 | pass(l); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /github_code/code/3/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/4/4.1.linear.container.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 4.1.linear.container.cpp 3 | // modern c++ tutorial 4 | // 5 | // created by changkun at changkun.de 6 | // https://github.com/changkun/modern-cpp-tutorial 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | void foo(int *p, int len) { 14 | for (int i = 0; i != len; ++i) { 15 | std::cout << p[i] << std::endl; 16 | } 17 | } 18 | 19 | int main() { 20 | std::vector v; 21 | std::cout << "size:" << v.size() << std::endl; // output 0 22 | std::cout << "capacity:" << v.capacity() << std::endl; // output 0 23 | 24 | // As you can see, the storage of std::vector is automatically managed and 25 | // automatically expanded as needed. 26 | // But if there is not enough space, you need to redistribute more memory, 27 | // and reallocating memory is usually a performance-intensive operation. 28 | v.push_back(1); 29 | v.push_back(2); 30 | v.push_back(3); 31 | std::cout << "size:" << v.size() << std::endl; // output 3 32 | std::cout << "capacity:" << v.capacity() << std::endl; // output 4 33 | 34 | // The auto-expansion logic here is very similar to Golang's slice. 35 | v.push_back(4); 36 | v.push_back(5); 37 | std::cout << "size:" << v.size() << std::endl; // output 5 38 | std::cout << "capacity:" << v.capacity() << std::endl; // output 8 39 | 40 | // As can be seen below, although the container empties the element, 41 | // the memory of the emptied element is not returned. 42 | v.clear(); 43 | std::cout << "size:" << v.size() << std::endl; // output 0 44 | std::cout << "capacity:" << v.capacity() << std::endl; // output 8 45 | 46 | // Additional memory can be returned to the system via the shrink_to_fit() call 47 | v.shrink_to_fit(); 48 | std::cout << "size:" << v.size() << std::endl; // output 0 49 | std::cout << "capacity:" << v.capacity() << std::endl; // output 0 50 | 51 | 52 | std::array arr= {1,4,3,2}; 53 | 54 | //int len = 4; 55 | //std::array arr = {1,2,3,4}; // illegal, size of array must be constexpr 56 | 57 | // C style parameter passing 58 | // foo(arr, arr.size()); // illegal, cannot convert implicitly 59 | foo(&arr[0], arr.size()); 60 | foo(arr.data(), arr.size()); 61 | 62 | // more usage 63 | std::sort(arr.begin(), arr.end()); 64 | for(auto &i : arr) 65 | std::cout << i << std::endl; 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /github_code/code/4/4.2.unordered.map.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 4.2.unordered.map.cpp 3 | // chapter 04 containers 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main() { 16 | // initialized in same order 17 | std::unordered_map u = { 18 | {1, "1"}, 19 | {3, "3"}, 20 | {2, "2"} 21 | }; 22 | std::map v = { 23 | {1, "1"}, 24 | {3, "3"}, 25 | {2, "2"} 26 | }; 27 | 28 | // iterates in the same way 29 | std::cout << "std::unordered_map" << std::endl; 30 | for( const auto & n : u) 31 | std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n"; 32 | 33 | std::cout << std::endl; 34 | std::cout << "std::map" << std::endl; 35 | for( const auto & n : v) 36 | std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n"; 37 | } 38 | -------------------------------------------------------------------------------- /github_code/code/4/4.3.tuples.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 4.3.tuples.cpp 3 | // chapter 04 containers 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | auto get_student(int id) 16 | { 17 | if (id == 0) 18 | return std::make_tuple(3.8, 'A', "John"); 19 | if (id == 1) 20 | return std::make_tuple(2.9, 'C', "Jack"); 21 | if (id == 2) 22 | return std::make_tuple(1.7, 'D', "Ive"); 23 | // return type is std::tuple 24 | return std::make_tuple(0.0, 'D', "null"); 25 | } 26 | 27 | template 28 | constexpr std::variant _tuple_index(const std::tuple& tpl, size_t i) { 29 | if constexpr (n >= sizeof...(T)) 30 | throw std::out_of_range("out of range."); 31 | if (i == n) 32 | return std::variant{ std::in_place_index, std::get(tpl) }; 33 | return _tuple_index<(n < sizeof...(T)-1 ? n+1 : 0)>(tpl, i); 34 | } 35 | template 36 | constexpr std::variant tuple_index(const std::tuple& tpl, size_t i) { 37 | return _tuple_index<0>(tpl, i); 38 | } 39 | 40 | template 41 | auto tuple_len(T &tpl) { 42 | return std::tuple_size::value; 43 | } 44 | 45 | template 46 | std::ostream & operator<< (std::ostream & s, std::variant const & v) { 47 | std::visit([&](auto && x){ s << x;}, v); 48 | return s; 49 | } 50 | 51 | int main() 52 | { 53 | auto student = get_student(0); 54 | std::cout << "ID: 0, " 55 | << "GPA: " << std::get<0>(student) << ", " 56 | << "Grade: " << std::get<1>(student) << ", " 57 | << "Name: " << std::get<2>(student) << '\n'; 58 | 59 | double gpa; 60 | char grade; 61 | std::string name; 62 | 63 | // tuple unpack 64 | std::tie(gpa, grade, name) = get_student(1); 65 | std::cout << "ID: 1, " 66 | << "GPA: " << gpa << ", " 67 | << "Grade: " << grade << ", " 68 | << "Name: " << name << '\n'; 69 | 70 | 71 | std::tuple t("123", 4.5, 6.7, 8); 72 | std::cout << std::get(t) << std::endl; 73 | // std::cout << std::get(t) << std::endl; // illegal, runtime error 74 | std::cout << std::get<3>(t) << std::endl; 75 | 76 | // concat 77 | auto new_tuple = std::tuple_cat(get_student(1), std::move(t)); 78 | 79 | // iteration 80 | for(int i = 0; i != tuple_len(new_tuple); ++i) { 81 | std::cout << tuple_index(new_tuple, i) << std::endl; // runtime indexing 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /github_code/code/4/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/5/5.1.shared.ptr.a.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 5.1.shared.ptr.cpp 3 | // chapter 05 start pointers and memory management 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | void foo(std::shared_ptr i) 14 | { 15 | (*i)++; 16 | } 17 | 18 | int main() 19 | { 20 | // auto pointer = new int(10); // illegal, no direct assignment 21 | // std::shared_ptr construction 22 | auto pointer = std::make_shared(10); 23 | auto pointer2 = pointer; // reference count + 1 24 | auto pointer3 = pointer; // reference count + 1 25 | 26 | 27 | foo(pointer); 28 | std::cout << *pointer << std::endl; // 11 29 | int *p = pointer.get(); // does not increase reference count 30 | 31 | std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; 32 | std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; 33 | std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; 34 | 35 | pointer2.reset(); 36 | std::cout << "reset pointer2:" << std::endl; 37 | std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; 38 | std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; 39 | std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; 40 | 41 | pointer3.reset(); 42 | std::cout << "reset pointer3:" << std::endl; 43 | std::cout << "pointer.use_count() = " << pointer.use_count() << std::endl; 44 | std::cout << "pointer2.use_count() = " << pointer2.use_count() << std::endl; 45 | std::cout << "pointer3.use_count() = " << pointer3.use_count() << std::endl; 46 | // std::cout << *pointer << std::endl; // reference count equals 0, illegal access 47 | 48 | 49 | // Before leaving the scope, the pointer is destructed and 50 | // the reference count is reduced to 0 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /github_code/code/5/5.2.unique.ptr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 5.2.unique.ptr.cpp 3 | // chapter 05 start pointers and memory management 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | struct Foo { 14 | Foo() { std::cout << "Foo::Foo" << std::endl; } 15 | ~Foo() { std::cout << "Foo::~Foo" << std::endl; } 16 | void foo() { std::cout << "Foo::foo" << std::endl; } 17 | }; 18 | 19 | void f(const Foo &) { 20 | std::cout << "f(const Foo&)" << std::endl; 21 | } 22 | 23 | int main() { 24 | std::unique_ptr p1(std::make_unique()); 25 | 26 | // p1 is not empty, prints 27 | if (p1) p1->foo(); 28 | { 29 | std::unique_ptr p2(std::move(p1)); 30 | 31 | // p2 is not empty, prints 32 | f(*p2); 33 | 34 | // p2 is not empty, prints 35 | if(p2) p2->foo(); 36 | 37 | // p1 is empty, no prints 38 | if(p1) p1->foo(); 39 | 40 | p1 = std::move(p2); 41 | 42 | // p2 is empty, no prints 43 | if(p2) p2->foo(); 44 | std::cout << "p2 was destroyed" << std::endl; 45 | } 46 | // p1 is not empty, prints 47 | if (p1) p1->foo(); 48 | 49 | // Foo instance will be destroyed when leaving the scope 50 | } 51 | -------------------------------------------------------------------------------- /github_code/code/5/5.3.weak.ptr.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 5.3.weak.ptr.cpp 3 | // chapter 05 start pointers and memory management 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | #include 13 | 14 | class A; 15 | class B; 16 | 17 | class A { 18 | public: 19 | std::shared_ptr pointer; 20 | ~A() { 21 | std::cout << "A was destroyed" << std::endl; 22 | } 23 | }; 24 | class B { 25 | public: 26 | std::shared_ptr pointer; 27 | ~B() { 28 | std::cout << "B was destroyed" << std::endl; 29 | } 30 | }; 31 | int main() { 32 | std::shared_ptr a = std::make_shared(); 33 | std::shared_ptr b = std::make_shared(); 34 | a->pointer = b; 35 | b->pointer = a; 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /github_code/code/5/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/6/6.1.regex.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 6.1.regex.cpp 3 | // chapter 06 regular expression 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int main() { 15 | std::string fnames[] = {"foo.txt", "bar.txt", "test", "a0.txt", "AAA.txt"}; 16 | // In C++, `\` will be used as an escape character in the string. 17 | // In order for `\.` to be passed as a regular expression, 18 | // it is necessary to perform second escaping of `\`, thus we have `\\.` 19 | std::regex txt_regex("[a-z]+\\.txt"); 20 | for (const auto &fname: fnames) 21 | std::cout << fname << ": " << std::regex_match(fname, txt_regex) << std::endl; 22 | 23 | std::regex base_regex("([a-z]+)\\.txt"); 24 | std::smatch base_match; 25 | for(const auto &fname: fnames) { 26 | if (std::regex_match(fname, base_match, base_regex)) { 27 | // the first element of std::smatch matches the entire string 28 | // the second element of std::smatch matches the first expression with brackets 29 | if (base_match.size() == 2) { 30 | std::string base = base_match[1].str(); 31 | std::cout << "sub-match[0]: " << base_match[0].str() << std::endl; 32 | std::cout << fname << " sub-match[1]: " << base << std::endl; 33 | } 34 | } 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /github_code/code/6/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/7/7.1.thread.basic.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.1.thread.basic.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | int main() { 14 | std::thread t([](){ 15 | std::cout << "hello world." << std::endl; 16 | }); 17 | t.join(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /github_code/code/7/7.2.critical.section.a.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.2.critical.section.a.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | int v = 1; 14 | 15 | void critical_section(int change_v) { 16 | static std::mutex mtx; 17 | std::lock_guard lock(mtx); 18 | 19 | // do contention operations 20 | v = change_v; 21 | 22 | // mtx will be destructed when exit this region 23 | } 24 | 25 | int main() { 26 | std::thread t1(critical_section, 2), t2(critical_section, 3); 27 | t1.join(); 28 | t2.join(); 29 | 30 | std::cout << v << std::endl; 31 | return 0; 32 | } -------------------------------------------------------------------------------- /github_code/code/7/7.3.critical.section.b.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.3.critical.section.b.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | int v = 1; 14 | 15 | void critical_section(int change_v) { 16 | static std::mutex mtx; 17 | std::unique_lock lock(mtx); 18 | // do contention operations 19 | v = change_v; 20 | std::cout << v << std::endl; 21 | // release the lock 22 | lock.unlock(); 23 | 24 | // during this period, 25 | // others are allowed to acquire v 26 | 27 | // start another group of contention operations 28 | // lock again 29 | lock.lock(); 30 | v += 1; 31 | std::cout << v << std::endl; 32 | } 33 | 34 | int main() { 35 | std::thread t1(critical_section, 2), t2(critical_section, 3); 36 | t1.join(); 37 | t2.join(); 38 | return 0; 39 | } -------------------------------------------------------------------------------- /github_code/code/7/7.4.futures.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.4.futures.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | int main() { 15 | // pack a lambda expression that returns 7 into a std::packaged_task 16 | std::packaged_task task([](){return 7;}); 17 | // get the future of task 18 | std::future result = task.get_future(); // run task in a thread 19 | std::thread(std::move(task)).detach(); 20 | std::cout << "waiting..."; 21 | result.wait(); // block until future has arrived 22 | // output result 23 | std::cout << "done!" << std:: endl << "future result is " << result.get() << std::endl; 24 | return 0; 25 | } -------------------------------------------------------------------------------- /github_code/code/7/7.5.producer.consumer.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.5.producer.consumer.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | int main() { 19 | std::queue produced_nums; 20 | std::mutex mtx; 21 | std::condition_variable cv; 22 | bool notified = false; // notification sign 23 | 24 | auto producer = [&]() { 25 | for (int i = 0; ; i++) { 26 | std::this_thread::sleep_for(std::chrono::milliseconds(500)); 27 | std::unique_lock lock(mtx); 28 | std::cout << "producing " << i << std::endl; 29 | produced_nums.push(i); 30 | notified = true; 31 | cv.notify_all(); 32 | } 33 | }; 34 | auto consumer = [&]() { 35 | while (true) { 36 | std::unique_lock lock(mtx); 37 | while (!notified) { // avoid spurious wakeup 38 | cv.wait(lock); 39 | } 40 | 41 | // temporal unlock to allow producer produces more rather than 42 | // let consumer hold the lock until its consumed. 43 | lock.unlock(); 44 | std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // consumer is slower 45 | lock.lock(); 46 | if (!produced_nums.empty()) { 47 | std::cout << "consuming " << produced_nums.front() << std::endl; 48 | produced_nums.pop(); 49 | } 50 | notified = false; 51 | } 52 | }; 53 | 54 | std::thread p(producer); 55 | std::thread cs[2]; 56 | for (int i = 0; i < 2; ++i) { 57 | cs[i] = std::thread(consumer); 58 | } 59 | p.join(); 60 | for (int i = 0; i < 2; ++i) { 61 | cs[i].join(); 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /github_code/code/7/7.6.atomic.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.6.atomic.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | std::atomic count = {0}; 15 | 16 | int main() { 17 | std::thread t1([](){ 18 | count.fetch_add(1); 19 | }); 20 | std::thread t2([](){ 21 | count++; // identical to fetch_add 22 | count += 1; // identical to fetch_add 23 | }); 24 | t1.join(); 25 | t2.join(); 26 | std::cout << count << std::endl; 27 | return 0; 28 | } -------------------------------------------------------------------------------- /github_code/code/7/7.6.bad.example.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.6.bad.example.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | int main() { 14 | int a = 0; 15 | volatile int flag = 0; 16 | 17 | std::thread t1([&]() { 18 | while (flag != 1); 19 | 20 | int b = a; 21 | std::cout << "b = " << b << std::endl; 22 | }); 23 | 24 | std::thread t2([&]() { 25 | a = 5; 26 | flag = 1; 27 | }); 28 | 29 | t1.join(); 30 | t2.join(); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /github_code/code/7/7.7.is.lock.free.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.7.is.lock.free.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | struct A { 14 | float x; 15 | int y; 16 | long long z; 17 | }; 18 | 19 | int main() { 20 | std::atomic a; 21 | std::cout << std::boolalpha << a.is_lock_free() << std::endl; 22 | return 0; 23 | } -------------------------------------------------------------------------------- /github_code/code/7/7.8.memory.order.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 7.8.memory.order.cpp 3 | // chapter 7 parallelism and concurrency 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | using namespace std::chrono; 17 | 18 | const int N = 10000; 19 | 20 | void relaxed_order() { 21 | cout << "relaxed_order: " << endl; 22 | 23 | atomic counter = {0}; 24 | vector vt; 25 | for (int i = 0; i < N; ++i) { 26 | vt.emplace_back([&](){ 27 | counter.fetch_add(1, memory_order_relaxed); 28 | }); 29 | } 30 | auto t1 = high_resolution_clock::now(); 31 | for (auto& t : vt) { 32 | t.join(); 33 | } 34 | auto t2 = high_resolution_clock::now(); 35 | auto duration = ( t2 - t1 ).count(); 36 | cout << "relaxed order speed: " << duration / N << "ns" << endl; 37 | } 38 | 39 | void release_consume_order() { 40 | cout << "release_consume_order: " << endl; 41 | 42 | atomic ptr; 43 | int v; 44 | thread producer([&]() { 45 | int* p = new int(42); 46 | v = 1024; 47 | ptr.store(p, memory_order_release); 48 | }); 49 | thread consumer([&]() { 50 | int* p; 51 | while(!(p = ptr.load(memory_order_consume))); 52 | 53 | cout << "p: " << *p << endl; 54 | cout << "v: " << v << endl; 55 | }); 56 | producer.join(); 57 | consumer.join(); 58 | } 59 | 60 | void release_acquire_order() { 61 | cout << "release_acquire_order: " << endl; 62 | 63 | int v; 64 | atomic flag = {0}; 65 | thread release([&]() { 66 | v = 42; 67 | flag.store(1, memory_order_release); 68 | }); 69 | thread acqrel([&]() { 70 | int expected = 1; // must before compare_exchange_strong 71 | while(!flag.compare_exchange_strong(expected, 2, memory_order_acq_rel)) { 72 | expected = 1; // must after compare_exchange_strong 73 | } 74 | // flag has changed to 2 75 | }); 76 | thread acquire([&]() { 77 | while(flag.load(memory_order_acquire) < 2); 78 | 79 | cout << "v: " << v << endl; // must be 42 80 | }); 81 | release.join(); 82 | acqrel.join(); 83 | acquire.join(); 84 | } 85 | 86 | void sequential_consistent_order() { 87 | cout << "sequential_consistent_order: " << endl; 88 | 89 | atomic counter = {0}; 90 | vector vt; 91 | for (int i = 0; i < N; ++i) { 92 | vt.emplace_back([&](){ 93 | counter.fetch_add(1, memory_order_seq_cst); 94 | }); 95 | } 96 | auto t1 = high_resolution_clock::now(); 97 | for (auto& t : vt) { 98 | t.join(); 99 | } 100 | auto t2 = high_resolution_clock::now(); 101 | auto duration = ( t2 - t1 ).count(); 102 | cout << "sequential consistent speed: " << duration / N << "ns" << endl; 103 | } 104 | 105 | int main() { 106 | relaxed_order(); 107 | release_consume_order(); 108 | release_acquire_order(); 109 | sequential_consistent_order(); 110 | return 0; 111 | } -------------------------------------------------------------------------------- /github_code/code/7/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/code/9/9.1.noexcept.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 9.1.noexcept.cpp 3 | // chapter 09 others 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | 12 | void may_throw() { 13 | throw true; 14 | } 15 | auto non_block_throw = []{ 16 | may_throw(); 17 | }; 18 | void no_throw() noexcept { 19 | return; 20 | } 21 | 22 | auto block_throw = []() noexcept { 23 | no_throw(); 24 | }; 25 | 26 | int main() 27 | { 28 | std::cout << std::boolalpha 29 | << "may_throw() noexcept? " << noexcept(may_throw()) << std::endl 30 | << "no_throw() noexcept? " << noexcept(no_throw()) << std::endl 31 | << "lmay_throw() noexcept? " << noexcept(non_block_throw()) << std::endl 32 | << "lno_throw() noexcept? " << noexcept(block_throw()) << std::endl; 33 | 34 | try { 35 | may_throw(); 36 | } catch (...) { 37 | std::cout << "exception captured from my_throw()" << std::endl; 38 | } 39 | 40 | try { 41 | non_block_throw(); 42 | } catch (...) { 43 | std::cout << "exception captured from non_block_throw()" << std::endl; 44 | } 45 | 46 | try { 47 | block_throw(); 48 | } catch (...) { 49 | std::cout << "exception captured from block_throw()" << std::endl; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /github_code/code/9/9.2.literals.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 9.2.literals.cpp 3 | // chapter 09 others 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | #include 11 | #include 12 | 13 | std::string operator"" _wow1(const char *wow1, size_t len) { 14 | return std::string(wow1)+"woooooooooow, amazing"; 15 | } 16 | 17 | std::string operator""_wow2 (unsigned long long i) { 18 | return std::to_string(i)+"woooooooooow, amazing"; 19 | } 20 | 21 | int main() { 22 | std::string str = R"(C:\\File\\To\\Path)"; 23 | std::cout << str << std::endl; 24 | 25 | int value = 0b1001010101010; 26 | std::cout << value << std::endl; 27 | 28 | 29 | auto str2 = "abc"_wow1; 30 | auto num = 1_wow2; 31 | std::cout << str2 << std::endl; 32 | std::cout << num << std::endl; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /github_code/code/9/9.3.alignment.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // 9.3.alignment.cpp 3 | // chapter 09 others 4 | // modern c++ tutorial 5 | // 6 | // created by changkun at changkun.de 7 | // https://github.com/changkun/modern-cpp-tutorial 8 | // 9 | 10 | 11 | #include 12 | 13 | struct Storage { 14 | char a; 15 | int b; 16 | double c; 17 | long long d; 18 | }; 19 | 20 | struct alignas(std::max_align_t) AlignasStorage { 21 | char a; 22 | int b; 23 | double c; 24 | long long d; 25 | }; 26 | 27 | int main() { 28 | std::cout << alignof(Storage) << std::endl; 29 | std::cout << alignof(AlignasStorage) << std::endl; 30 | return 0; 31 | } -------------------------------------------------------------------------------- /github_code/code/9/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # modern cpp tutorial 3 | # 4 | # created by changkun at changkun.de 5 | # https://github.com/changkun/modern-cpp-tutorial 6 | # 7 | 8 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 9 | 10 | %.out: %.cpp Makefile 11 | clang++ $< -o $@ -std=c++2a -pedantic 12 | 13 | clean: 14 | rm *.out -------------------------------------------------------------------------------- /github_code/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:latest 2 | 3 | LABEL "maintainer"="Changkun Ou " 4 | LABEL "repository"="https://github.com/changkun/modern-cpp-tutorial" 5 | LABEL "homepage"="https://changkun.de/modern-cpp/" 6 | 7 | # FUCKING UNICODE 8 | ENV LANG C.UTF-8 9 | ENV LC_ALL C.UTF-8 10 | 11 | WORKDIR /modern-cpp-tutorial 12 | 13 | # Node & Npm & Python3 are from node:latest 14 | # Install Texlive & Pandoc 15 | RUN apt update && \ 16 | apt install wget texlive-full -y && \ 17 | wget https://github.com/jgm/pandoc/releases/download/2.7.3/pandoc-2.7.3-1-amd64.deb && \ 18 | dpkg -i pandoc-2.7.3-1-amd64.deb 19 | -------------------------------------------------------------------------------- /github_code/epub/en-us/Makefile: -------------------------------------------------------------------------------- 1 | title = 'Modern C++ Tutorial: C++11/14/17/20 On the Fly' 2 | filename = 'modern-cpp-tutorial' 3 | outputname='modern-cpp-tutorial' 4 | revision = $(shell git describe --always --tags) 5 | date = $(shell date +'%Y.%m.%d-%H:%M') 6 | all: revision epub 7 | 8 | revision: 9 | @echo '---' >> meta.markdown 10 | @echo 'title: "Modern C++ Tutorial: C++11/14/17/20 On the Fly"' >> meta.markdown 11 | @echo 'author: Changkun Ou ' >> meta.markdown 12 | @echo 'subtitle: |' >> meta.markdown 13 | @echo ' The content in this PDF file may outdated, please check our website or GitHub repository for the latest book updates. Last update: ${date}' >> meta.markdown 14 | @echo 'rights: © Ou Changkun, CC BY-NC-ND 4.0.' >> meta.markdown 15 | @echo 'ibooks:' >> meta.markdown 16 | @echo ' - version: ${revision}' >> meta.markdown 17 | @echo '---' >> meta.markdown 18 | 19 | epub: markdown 20 | @echo "Compiling PDF file..." 21 | pandoc -f markdown+smart --toc -t epub -o $(filename).epub \ 22 | --highlight-style haddock \ 23 | --epub-cover-image ../../assets/cover-2nd-en.png \ 24 | --title-prefix $(title) \ 25 | meta.markdown \ 26 | 00-preface.md.markdown \ 27 | 01-intro.md.markdown \ 28 | 02-usability.md.markdown \ 29 | 03-runtime.md.markdown \ 30 | 04-containers.md.markdown \ 31 | 05-pointers.md.markdown \ 32 | 06-regex.md.markdown \ 33 | 07-thread.md.markdown \ 34 | 08-filesystem.md.markdown \ 35 | 09-others.md.markdown \ 36 | 10-cpp20.md.markdown \ 37 | appendix1.md.markdown \ 38 | appendix2.md.markdown 39 | @echo "Done." 40 | rm -f *.md *.markdown 41 | 42 | markdown: 43 | @echo "Copy markdown files..." 44 | cp -r ../../book/en-us/* . 45 | @echo "Aggregating markdown files..." 46 | python3 filter.py 47 | 48 | clean: 49 | rm -rf *.md *.markdown 50 | 51 | .PHONY: markdown epub clean -------------------------------------------------------------------------------- /github_code/epub/en-us/filter.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # author: changkun 3 | 4 | import os 5 | 6 | chapters = ['00-preface.md', '01-intro.md', '02-usability.md', '03-runtime.md', '04-containers.md', '05-pointers.md', '06-regex.md', '07-thread.md', '08-filesystem.md', '09-others.md', '10-cpp20.md', 'appendix1.md', 'appendix2.md'] 7 | 8 | ignores = ['TOC', 'Table of Content', 'License', 'license'] 9 | 10 | for chapter in chapters: 11 | with open(chapter+'.markdown', 'w') as outfile: 12 | if os.path.isfile(chapter): 13 | with open(chapter) as ch: 14 | outfile.write('\n') 15 | for line in ch: 16 | if any(keyword in line for keyword in ignores): 17 | continue 18 | else: 19 | outfile.write(line) -------------------------------------------------------------------------------- /github_code/epub/zh-cn/Makefile: -------------------------------------------------------------------------------- 1 | title = '现代 C++ 教程:高速上手 C++11/14/17/20' 2 | filename = 'modern-cpp-tutorial' 3 | outputname='modern-cpp-tutorial' 4 | revision = $(shell git describe --always --tags) 5 | date = $(shell date +'%Y.%m.%d-%H:%M') 6 | all: revision epub 7 | 8 | revision: 9 | @echo '---' >> meta.markdown 10 | @echo 'title: "现代 C++ 教程:高速上手 C++11/14/17/20"' >> meta.markdown 11 | @echo 'author: 欧长坤 ' >> meta.markdown 12 | @echo 'subtitle: |' >> meta.markdown 13 | @echo ' 此文件的内容可能过期,请检查本书网站 及 GitHub 仓库 以获取最新内容。最后更新:${date}' >> meta.markdown 14 | @echo 'rights: © Ou Changkun, CC BY-NC-ND 4.0.' >> meta.markdown 15 | @echo 'ibooks:' >> meta.markdown 16 | @echo ' - version: ${revision}' >> meta.markdown 17 | @echo '---' >> meta.markdown 18 | 19 | epub: markdown 20 | @echo "Compiling PDF file..." 21 | pandoc -f markdown+smart --toc -t epub -o $(filename).epub \ 22 | --highlight-style haddock \ 23 | --epub-cover-image ../../assets/cover-2nd.png \ 24 | --title-prefix $(title) \ 25 | meta.markdown \ 26 | 00-preface.md.markdown \ 27 | 01-intro.md.markdown \ 28 | 02-usability.md.markdown \ 29 | 03-runtime.md.markdown \ 30 | 04-containers.md.markdown \ 31 | 05-pointers.md.markdown \ 32 | 06-regex.md.markdown \ 33 | 07-thread.md.markdown \ 34 | 08-filesystem.md.markdown \ 35 | 09-others.md.markdown \ 36 | 10-cpp20.md.markdown \ 37 | appendix1.md.markdown \ 38 | appendix2.md.markdown 39 | @echo "Done." 40 | rm -f *.md *.markdown 41 | 42 | markdown: 43 | @echo "Copy markdown files..." 44 | cp -r ../../book/zh-cn/* . 45 | @echo "Aggregating markdown files..." 46 | python3 filter.py 47 | 48 | clean: 49 | rm -rf *.md *.markdown 50 | 51 | .PHONY: markdown epub clean -------------------------------------------------------------------------------- /github_code/epub/zh-cn/filter.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # author: changkun 3 | 4 | import os 5 | 6 | chapters = ['00-preface.md', '01-intro.md', '02-usability.md', '03-runtime.md', '04-containers.md', '05-pointers.md', '06-regex.md', '07-thread.md', '08-filesystem.md', '09-others.md', '10-cpp20.md', 'appendix1.md', 'appendix2.md'] 7 | 8 | ignores = ['TOC', '返回目录', '许可', 'license'] 9 | 10 | for chapter in chapters: 11 | with open(chapter+'.markdown', 'w') as outfile: 12 | if os.path.isfile(chapter): 13 | with open(chapter) as ch: 14 | outfile.write('\n') 15 | for line in ch: 16 | if any(keyword in line for keyword in ignores): 17 | continue 18 | else: 19 | outfile.write(line) -------------------------------------------------------------------------------- /github_code/exercises/2/fold.expresion.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // fold.expression.cpp 3 | // 4 | // exercise solution - chapter 2 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial 9 | // 10 | 11 | #include 12 | template 13 | auto average(T ... t) { 14 | return (t + ... ) / sizeof...(t); 15 | } 16 | int main() { 17 | std::cout << average(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << std::endl; 18 | } -------------------------------------------------------------------------------- /github_code/exercises/2/structured.binding.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // structured.binding.cpp 3 | // 4 | // exercise solution - chapter 2 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial 9 | // 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | template 17 | void update(std::map& m, F foo) { 18 | for (auto&& [key, value] : m ) value = foo(key); 19 | } 20 | 21 | int main() { 22 | std::map m { 23 | {"a", 1}, 24 | {"b", 2}, 25 | {"c", 3} 26 | }; 27 | update(m, [](std::string key) -> long long int { 28 | return std::hash{}(key); 29 | }); 30 | for (auto&& [key, value] : m) 31 | std::cout << key << ":" << value << std::endl; 32 | } -------------------------------------------------------------------------------- /github_code/exercises/6/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # web_server 4 | # 5 | # created by changkun at changkun.de/modern-cpp 6 | # 7 | 8 | CXX = g++ 9 | EXEC_HTTP = server.http 10 | EXEC_HTTPS = server.https 11 | 12 | SOURCE_HTTP = main.http.cpp 13 | SOURCE_HTTPS = main.https.cpp 14 | 15 | OBJECTS_HTTP = main.http.o 16 | OBJECTS_HTTPS = main.https.o 17 | 18 | LDFLAGS_COMMON = -std=c++2a -O3 -pthread -lboost_system 19 | LDFLAGS_HTTP = 20 | LDFLAGS_HTTPS = -lssl -lcrypto 21 | 22 | LPATH_COMMON = -I/usr/include/boost 23 | LPATH_HTTP = 24 | LPATH_HTTPS = -I/usr/local/opt/openssl/include 25 | 26 | LLIB_COMMON = -L/usr/lib 27 | LLIB_HTTPS = -L/usr/local/opt/openssl/lib 28 | 29 | all: 30 | make http 31 | make https 32 | 33 | http: 34 | $(CXX) $(SOURCE_HTTP) $(LDFLAGS_COMMON) $(LDFLAGS_HTTP) $(LPATH_COMMON) $(LPATH_HTTP) $(LLIB_COMMON) $(LLIB_HTTP) -o $(EXEC_HTTP) 35 | https: 36 | $(CXX) $(SOURCE_HTTPS) $(LDFLAGS_COMMON) $(LDFLAGS_HTTPS) $(LPATH_COMMON) $(LPATH_HTTPS) $(LLIB_COMMON) $(LLIB_HTTPS) -o $(EXEC_HTTPS) 37 | 38 | clean: 39 | rm -f $(EXEC_HTTP) $(EXEC_HTTPS) *.o 40 | -------------------------------------------------------------------------------- /github_code/exercises/6/handler.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // handler.hpp 3 | // web_server 4 | // created by changkun at changkun.de 5 | // https://github.com/changkun/modern-cpp-tutorial/ 6 | // 7 | 8 | #include "server.base.hpp" 9 | #include 10 | 11 | using namespace std; 12 | using namespace Web; 13 | 14 | template 15 | void start_server(SERVER_TYPE &server) { 16 | // resources request 17 | 18 | // processing POST /string, return the string from POST 19 | server.resource["^/string/?$"]["POST"] = [](ostream& response, Request& request) { 20 | // fetch string from istream (*request.content) 21 | stringstream ss; 22 | *request.content >> ss.rdbuf(); // read request to stringstream 23 | string content=ss.str(); 24 | 25 | // return response 26 | response << "HTTP/1.1 200 OK\r\nContent-Length: " << content.length() << "\r\n\r\n" << content; 27 | }; 28 | 29 | // process GET request from /info, return response 30 | server.resource["^/info/?$"]["GET"] = [](ostream& response, Request& request) { 31 | stringstream content_stream; 32 | content_stream << "

Request:

"; 33 | content_stream << request.method << " " << request.path << " HTTP/" << request.http_version << "
"; 34 | for(auto& header: request.header) { 35 | content_stream << header.first << ": " << header.second << "
"; 36 | } 37 | 38 | // get the length of content_stream (use content.tellp() to get) 39 | content_stream.seekp(0, ios::end); 40 | 41 | response << "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n" << content_stream.rdbuf(); 42 | }; 43 | 44 | // process GET request for /match/[digit+numbers], e.g. GET request is /match/abc123, will return abc123 45 | server.resource["^/match/([0-9a-zA-Z]+)/?$"]["GET"] = [](ostream& response, Request& request) { 46 | string number=request.path_match[1]; 47 | response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number; 48 | }; 49 | 50 | // peocess default GET request; anonymous function will be called if no other matches 51 | // response files in folder web/ 52 | // default: index.html 53 | server.default_resource["^/?(.*)$"]["GET"] = [](ostream& response, Request& request) { 54 | string filename = "www/"; 55 | 56 | string path = request.path_match[1]; 57 | 58 | // forbidden use `..` access content outside folder web/ 59 | size_t last_pos = path.rfind("."); 60 | size_t current_pos = 0; 61 | size_t pos; 62 | while((pos=path.find('.', current_pos)) != string::npos && pos != last_pos) { 63 | current_pos = pos; 64 | path.erase(pos, 1); 65 | last_pos--; 66 | } 67 | 68 | filename += path; 69 | ifstream ifs; 70 | // folder inspection across platform 71 | if(filename.find('.') == string::npos) { 72 | if(filename[filename.length()-1]!='/') 73 | filename+='/'; 74 | filename += "index.html"; 75 | } 76 | ifs.open(filename, ifstream::in); 77 | 78 | if(ifs) { 79 | ifs.seekg(0, ios::end); 80 | size_t length=ifs.tellg(); 81 | 82 | ifs.seekg(0, ios::beg); 83 | 84 | // copy file to response-stream , shouldn't use for large files 85 | response << "HTTP/1.1 200 OK\r\nContent-Length: " << length << "\r\n\r\n" << ifs.rdbuf(); 86 | 87 | ifs.close(); 88 | } else { 89 | // return unable to open if file doesn't exists 90 | string content="Could not open file "+filename; 91 | response << "HTTP/1.1 400 Bad Request\r\nContent-Length: " << content.length() << "\r\n\r\n" << content; 92 | } 93 | }; 94 | 95 | // start HTTP(S) server 96 | server.start(); 97 | } 98 | -------------------------------------------------------------------------------- /github_code/exercises/6/main.http.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main_http.cpp 3 | // web_server 4 | // created by changkun at changkun.de 5 | // https://github.com/changkun/modern-cpp-tutorial/ 6 | // 7 | 8 | #include 9 | #include "server.http.hpp" 10 | #include "handler.hpp" 11 | 12 | using namespace Web; 13 | 14 | int main() { 15 | // HTTP server runs in port 12345 HTTP, enable 4 threads 16 | Server server(12345, 4); 17 | std::cout << "Server starting at port: 12345" << std::endl; 18 | start_server>(server); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /github_code/exercises/6/main.https.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main_https.cpp 3 | // web_server 4 | // created by changkun at changkun.de 5 | // https://github.com/changkun/modern-cpp-tutorial/ 6 | // 7 | #include 8 | #include "server.https.hpp" 9 | #include "handler.hpp" 10 | using namespace Web; 11 | 12 | int main() { 13 | // HTTPS server runs in port 12345, enable 4 threads 14 | // Use certificates for security 15 | Server server(12345, 4, "server.crt", "server.key"); 16 | std::cout << "Server starting at port: 12345" << std::endl; 17 | start_server>(server); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /github_code/exercises/6/server.http.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // server_http.hpp 3 | // web_server 4 | // created by changkun at changkun.de 5 | // https://github.com/changkun/modern-cpp-tutorial/ 6 | // 7 | 8 | #ifndef SERVER_HTTP_HPP 9 | #define SERVER_HTTP_HPP 10 | 11 | #include "server.base.hpp" 12 | 13 | namespace Web { 14 | typedef boost::asio::ip::tcp::socket HTTP; 15 | template<> 16 | class Server : public ServerBase { 17 | public: 18 | // use port, thread number to construct web server 19 | // http server is much simple than https since it doesn't need to initial config file 20 | Server(unsigned short port, size_t num_threads=1) : 21 | ServerBase::ServerBase(port, num_threads) {}; 22 | private: 23 | // implement accept() method 24 | void accept() { 25 | // create a new socket for current connection 26 | // shared_ptr is used for passing temporal object to anonymous function 27 | // socket will be deduce as type of std::shared_ptr 28 | auto socket = std::make_shared(m_io_service); 29 | 30 | acceptor.async_accept(*socket, [this, socket](const boost::system::error_code& ec) { 31 | // establish a connection 32 | accept(); 33 | // if no error 34 | if(!ec) process_request_and_respond(socket); 35 | }); 36 | } 37 | }; 38 | } 39 | #endif /* SERVER_HTTP_HPP */ 40 | -------------------------------------------------------------------------------- /github_code/exercises/6/server.https.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // server_https.hpp 3 | // web_server 4 | // created by changkun at changkun.de 5 | // https://github.com/changkun/modern-cpp-tutorial/ 6 | // 7 | 8 | #ifndef SERVER_HTTPS_HPP 9 | #define SERVER_HTTPS_HPP 10 | 11 | #include "server.http.hpp" 12 | #include 13 | 14 | namespace Web { 15 | 16 | // define HTTPS type 17 | typedef boost::asio::ssl::stream HTTPS; 18 | 19 | // define HTTPS service, template type is HTTPS 20 | template<> 21 | class Server : public ServerBase { 22 | public: 23 | // a HTTPS server requires two more parameters: certificate file and private key file 24 | Server(unsigned short port, size_t num_threads, 25 | const std::string& cert_file, const std::string& private_key_file) : 26 | ServerBase::ServerBase(port, num_threads), 27 | context(boost::asio::ssl::context::sslv23) { 28 | // use certificate file 29 | context.use_certificate_chain_file(cert_file); 30 | // use private key file, we need pass a new parameter to specify the format 31 | context.use_private_key_file(private_key_file, boost::asio::ssl::context::pem); 32 | } 33 | 34 | private: 35 | // compare to HTTP server, we must define ssl context object 36 | boost::asio::ssl::context context; 37 | 38 | // the difference between HTTPS and HTTP server 39 | // is the construct difference of socket object 40 | // HTTPS will encrypt the IO stream socket 41 | // thus, accept() method must initialize ssl context 42 | void accept() { 43 | // create a new socket for current connection 44 | // shared_ptr is used for passing temporal object to anonymous function 45 | // socket will be deduce as std::shared_ptr 46 | auto socket = std::make_shared(m_io_service, context); 47 | 48 | acceptor.async_accept( 49 | (*socket).lowest_layer(), 50 | [this, socket](const boost::system::error_code& ec) { 51 | // accept a new connection 52 | accept(); 53 | 54 | // if no error 55 | if(!ec) { 56 | (*socket).async_handshake(boost::asio::ssl::stream_base::server, 57 | [this, socket](const boost::system::error_code& ec) { 58 | if(!ec) process_request_and_respond(socket); 59 | }); 60 | } 61 | }); 62 | } 63 | }; 64 | } 65 | 66 | #endif /* SERVER_HTTPS_HPP */ 67 | -------------------------------------------------------------------------------- /github_code/exercises/6/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Web Server Test 4 | 5 | 6 | Hello world in index.html. 7 | 8 | 9 | -------------------------------------------------------------------------------- /github_code/exercises/6/www/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Web Server Test 4 | 5 | 6 | Hello world in test.html. 7 | 8 | 9 | -------------------------------------------------------------------------------- /github_code/exercises/7/7.1/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # 4 | # exercise solution 7.1 - chapter 7 5 | # modern cpp tutorial 6 | # 7 | # created by changkun at changkun.de/modern-cpp 8 | # 9 | 10 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 11 | 12 | %.out: %.cpp Makefile 13 | clang++ $< -o $@ -std=c++2a -pedantic 14 | 15 | clean: 16 | rm *.out -------------------------------------------------------------------------------- /github_code/exercises/7/7.1/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // 4 | // exercise solution - chapter 7 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial/ 9 | // 10 | 11 | #include // std::cout, std::endl 12 | 13 | #include // std::vector 14 | #include // std::string 15 | #include // std::future 16 | #include // std::this_thread::sleep_for 17 | #include // std::chrono::seconds 18 | 19 | #include "thread_pool.hpp" 20 | 21 | int main() 22 | { 23 | // create a thread pool with max. 4 concurrency threads 24 | ThreadPool pool(4); 25 | // create execution results list 26 | std::vector< std::future > results; 27 | 28 | // start eight thread task 29 | for(int i = 0; i < 8; ++i) { 30 | // add all task to result list 31 | results.emplace_back( 32 | // ass print task to thread pool 33 | pool.enqueue([i] { 34 | std::cout << "hello " << i << std::endl; 35 | // wait a sec when the previous line is out 36 | std::this_thread::sleep_for(std::chrono::seconds(1)); 37 | // keep output and return the status of execution 38 | std::cout << "world " << i << std::endl; 39 | return std::string("---thread ") + std::to_string(i) + std::string(" finished.---"); 40 | }) 41 | ); 42 | } 43 | 44 | // outputs 45 | for(auto && result: results) 46 | std::cout << result.get() << ' '; 47 | std::cout << std::endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /github_code/exercises/7/7.1/thread_pool.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // thread_pool.hpp 3 | // 4 | // exercise solution - chapter 7 5 | // modern cpp tutorial 6 | // 7 | // created by changkun at changkun.de 8 | // https://github.com/changkun/modern-cpp-tutorial/ 9 | // 10 | 11 | #ifndef THREAD_POOL_H 12 | #define THREAD_POOL_H 13 | 14 | #include // std::vector 15 | #include // std::queue 16 | #include // std::make_shared 17 | 18 | #include // std::thread 19 | #include // std::mutex, std::unique_lock 20 | #include // std::condition_variable 21 | #include // std::future, std::packaged_task 22 | 23 | #include // std::function, std::bind 24 | #include // std::runtime_error 25 | #include // std::move, std::forward 26 | 27 | class ThreadPool { 28 | public: 29 | 30 | // initialize the number of concurrency threads 31 | ThreadPool(size_t); 32 | 33 | // enqueue new thread task 34 | template 35 | decltype(auto) enqueue(F&& f, Args&&... args); 36 | 37 | // destroy thread pool and all created threads 38 | ~ThreadPool(); 39 | private: 40 | 41 | // thread list, stores all threads 42 | std::vector< std::thread > workers; 43 | // queue task, the type of queue elements are functions with void return type 44 | std::queue< std::function > tasks; 45 | 46 | // for synchonization 47 | std::mutex queue_mutex; 48 | // std::condition_variable is a new feature from c++11, 49 | // it's a synchronization primitives. it can be used 50 | // to block a thread or threads at the same time until 51 | // all of them modified condition_variable. 52 | std::condition_variable condition; 53 | bool stop; 54 | }; 55 | 56 | // constructor initialize a fixed size of worker 57 | inline ThreadPool::ThreadPool(size_t threads): stop(false) { 58 | // initialize worker 59 | for(size_t i = 0;i task; 68 | 69 | // critical section 70 | { 71 | // get mutex 72 | std::unique_lock lock(this->queue_mutex); 73 | 74 | // block current thread 75 | this->condition.wait(lock, 76 | [this]{ return this->stop || !this->tasks.empty(); }); 77 | 78 | // return if queue empty and task finished 79 | if(this->stop && this->tasks.empty()) 80 | return; 81 | 82 | // otherwise execute the first element of queue 83 | task = std::move(this->tasks.front()); 84 | this->tasks.pop(); 85 | } 86 | 87 | // execution 88 | task(); 89 | } 90 | } 91 | ); 92 | } 93 | 94 | // Enqueue a new thread 95 | // use variadic templates and tail return type 96 | template 97 | decltype(auto) ThreadPool::enqueue(F&& f, Args&&... args) { 98 | // deduce return type 99 | using return_type = typename std::result_of::type; 100 | 101 | // fetch task 102 | auto task = std::make_shared>( 103 | std::bind(std::forward(f), std::forward(args)...) 104 | ); 105 | 106 | std::future res = task->get_future(); 107 | 108 | // critical section 109 | { 110 | std::unique_lock lock(queue_mutex); 111 | 112 | // avoid add new thread if theadpool is destroyed 113 | if(stop) 114 | throw std::runtime_error("enqueue on stopped ThreadPool"); 115 | 116 | // add thread to queue 117 | tasks.emplace([task]{ (*task)(); }); 118 | } 119 | 120 | // notify a wait thread 121 | condition.notify_one(); 122 | return res; 123 | } 124 | 125 | // destroy everything 126 | inline ThreadPool::~ThreadPool() 127 | { 128 | // critical section 129 | { 130 | std::unique_lock lock(queue_mutex); 131 | stop = true; 132 | } 133 | 134 | // wake up all threads 135 | condition.notify_all(); 136 | 137 | // let all processes into synchronous execution, use c++11 new for-loop: for(value:values) 138 | for(std::thread &worker: workers) 139 | worker.join(); 140 | } 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /github_code/exercises/7/7.2.mutex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class mutex { 6 | std::atomic flag{false}; 7 | 8 | public: 9 | void lock() 10 | { 11 | while (flag.exchange(true, std::memory_order_relaxed)); 12 | std::atomic_thread_fence(std::memory_order_acquire); 13 | } 14 | 15 | void unlock() 16 | { 17 | std::atomic_thread_fence(std::memory_order_release); 18 | flag.store(false, std::memory_order_relaxed); 19 | } 20 | }; 21 | 22 | int a = 0; 23 | 24 | int main() { 25 | 26 | mutex mtx_a; 27 | 28 | std::thread t1([&](){ 29 | mtx_a.lock(); 30 | a += 1; 31 | mtx_a.unlock(); 32 | }); 33 | std::thread t2([&](){ 34 | mtx_a.lock(); 35 | a += 2; 36 | mtx_a.unlock(); 37 | }); 38 | 39 | t1.join(); 40 | t2.join(); 41 | 42 | std::cout << a << std::endl; 43 | return 0; 44 | } -------------------------------------------------------------------------------- /github_code/exercises/7/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile 3 | # 4 | # exercise solution - chapter 7 5 | # modern cpp tutorial 6 | # 7 | # created by changkun at changkun.de/modern-cpp 8 | # 9 | 10 | all: $(patsubst %.cpp, %.out, $(wildcard *.cpp)) 11 | 12 | %.out: %.cpp Makefile 13 | clang++ $< -o $@ -std=c++2a -pedantic 14 | 15 | clean: 16 | rm *.out -------------------------------------------------------------------------------- /github_code/pdf/en-us/Makefile: -------------------------------------------------------------------------------- 1 | title = 'Modern C++ Tutorial: C++11/14/17/20 On the Fly' 2 | filename = 'modern-cpp-tutorial' 3 | outputname='modern-cpp-tutorial' 4 | revision = $(shell git describe --always --tags) 5 | 6 | all: revision pdf 7 | 8 | revision: 9 | @echo '% Autogenerated, do not edit' > revision.tex 10 | @echo '\\newcommand{\\revision}{'$(revision)'}' >> revision.tex 11 | 12 | pdf: markdown 13 | @echo "Compiling PDF file..." 14 | pandoc -f markdown+smart -s $(filename).md -o $(filename).pdf \ 15 | --title-prefix $(title) \ 16 | --template=meta/template.tex \ 17 | --pdf-engine=`which xelatex` 18 | @echo "Done." 19 | rm *.md revision.tex 20 | 21 | markdown: 22 | @echo "Copy markdown files..." 23 | cp -r ../../book/en-us/* . 24 | @echo "Aggregating markdown files..." 25 | python3 aggregator.py 26 | 27 | clean: 28 | rm -rf revision.tex *.md 29 | 30 | .PHONY: markdown pdf clean -------------------------------------------------------------------------------- /github_code/pdf/en-us/aggregator.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # author: changkun 3 | 4 | import os 5 | 6 | chapters = ['00-preface.md', '01-intro.md', '02-usability.md', '03-runtime.md', '04-containers.md', '05-pointers.md', '06-regex.md', '07-thread.md', '08-filesystem.md', '09-others.md', '10-cpp20.md', 'appendix1.md', 'appendix2.md'] 7 | 8 | ignores = ['TOC', 'Table of Content', 'License', 'license'] 9 | 10 | 11 | with open('modern-cpp-tutorial.md', 'w') as outfile: 12 | outfile.write("""--- 13 | title: "Modern C++ Tutorial: C++11/14/17/20 On the Fly" 14 | author: Changkun Ou 15 | copyright: cc-by-nc-nd 4.0 16 | --- 17 | """) 18 | for chapter in chapters: 19 | if os.path.isfile(chapter): 20 | with open(chapter) as ch: 21 | outfile.write('\n') 22 | for line in ch: 23 | if any(keyword in line for keyword in ignores): 24 | continue 25 | else: 26 | outfile.write(line) -------------------------------------------------------------------------------- /github_code/pdf/en-us/meta/template.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper, 10pt]{article} 2 | \usepackage{geometry} 3 | \geometry{ 4 | top=1in, 5 | inner=1in, 6 | outer=1in, 7 | bottom=1in, 8 | headheight=3ex, 9 | headsep=2ex 10 | } 11 | \usepackage{tabu} 12 | \usepackage[T1]{fontenc} 13 | \usepackage{lmodern} 14 | \usepackage{booktabs} 15 | \usepackage{amssymb,amsmath} 16 | \usepackage{ifxetex,ifluatex} 17 | 18 | \linespread{1.2}\selectfont 19 | \ifxetex 20 | \usepackage{xltxtra,xunicode} 21 | \fi 22 | $if(mainfont)$ 23 | \setmainfont{$mainfont$} 24 | $endif$ 25 | $if(sansfont)$ 26 | \setsansfont{$sansfont$} 27 | $endif$ 28 | $if(monofont)$ 29 | \setmonofont{$monofont$} 30 | $endif$ 31 | $if(mathfont)$ 32 | \setmathfont{$mathfont$} 33 | $endif$ 34 | 35 | % use microtype if available 36 | \IfFileExists{microtype.sty}{\usepackage{microtype}}{} 37 | $if(geometry)$ 38 | \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} 39 | $endif$ 40 | $if(natbib)$ 41 | \usepackage{natbib} 42 | \bibliographystyle{plainnat} 43 | $endif$ 44 | $if(biblatex)$ 45 | \usepackage{biblatex} 46 | $if(biblio-files)$ 47 | \bibliography{$biblio-files$} 48 | $endif$ 49 | $endif$ 50 | \usepackage{listings} 51 | $if(lhs)$ 52 | \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} 53 | $endif$ 54 | $if(highlighting-macros)$ 55 | $highlighting-macros$ 56 | $endif$ 57 | $if(verbatim-in-note)$ 58 | \usepackage{fancyvrb} 59 | $endif$ 60 | $if(tables)$ 61 | \usepackage{longtable} 62 | $endif$ 63 | 64 | \usepackage{graphicx} 65 | \usepackage{caption} 66 | 67 | % We will generate all images so they have a width \maxwidth. This means 68 | % that they will get their normal width if they fit onto the page, but 69 | % are scaled down if they would overflow the margins. 70 | \makeatletter 71 | \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth 72 | \else\Gin@nat@width\fi} 73 | \makeatother 74 | \let\Oldincludegraphics\includegraphics 75 | \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=0.7\maxwidth]{#1}} 76 | \ifxetex 77 | \usepackage[setpagesize=false, % page size defined by xetex 78 | unicode=false, % unicode breaks when used with xetex 79 | xetex]{hyperref} 80 | \else 81 | \usepackage[unicode=true]{hyperref} 82 | \fi 83 | \hypersetup{breaklinks=true, 84 | bookmarks=true, 85 | pdfauthor={$author-meta$}, 86 | pdftitle={$title-meta$}, 87 | colorlinks=true, 88 | urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$, 89 | linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$, 90 | pdfborder={0 0 0}} 91 | \urlstyle{same} % don't use monospace font for urls 92 | $if(links-as-notes)$ 93 | % Make links footnotes instead of hotlinks: 94 | \renewcommand{\href}[2]{#2\footnote{\url{#1}}} 95 | $endif$ 96 | $if(strikeout)$ 97 | \usepackage[normalem]{ulem} 98 | % avoid problems with \sout in headers with hyperref: 99 | \pdfstringdefDisableCommands{\renewcommand{\sout}{}} 100 | $endif$ 101 | \setlength{\parindent}{10pt} 102 | %\setlength{\parskip}{6pt plus 2pt minus 1pt} 103 | \setlength{\emergencystretch}{3em} % prevent overfull lines 104 | \usepackage{titling} 105 | %\setlength{\droptitle}{-8em} % 将标题移动至页面上方 106 | 107 | \usepackage{fancyhdr} 108 | \usepackage{lastpage} 109 | \pagestyle{fancyplain} 110 | 111 | $if(numbersections)$ 112 | \setcounter{secnumdepth}{5} 113 | $else$ 114 | \setcounter{secnumdepth}{0} 115 | $endif$ 116 | $if(verbatim-in-note)$ 117 | \VerbatimFootnotes % allows verbatim text in footnotes 118 | $endif$ 119 | $if(lang)$ 120 | \ifxetex 121 | \usepackage{polyglossia} 122 | \setmainlanguage{$mainlang$} 123 | \else 124 | \usepackage[$lang$]{babel} 125 | \fi 126 | $endif$ 127 | $for(header-includes)$ 128 | $header-includes$ 129 | $endfor$ 130 | 131 | $if(title)$ 132 | \title{$title$} 133 | $endif$ 134 | \author{$for(author)$$author$$sep$ \and $endfor$} 135 | \date{$date$} 136 | 137 | \makeatletter 138 | \let\@afterindentfalse\@afterindenttrue 139 | \@afterindenttrue 140 | \makeatother 141 | \setlength{\parindent}{2em} 142 | 143 | \linespread{1.4} 144 | \setlength{\parskip}{1ex} 145 | \setlength{\parskip}{0.5\baselineskip} 146 | 147 | \input{revision} 148 | % fix build, see https://github.com/laboon/ebook/issues/139#issuecomment-408696480 149 | 150 | \newcommand{\passthrough}[1]{\lstset{mathescape=false}#1\lstset{mathescape=true}} 151 | \begin{document} 152 | 153 | \newcommand{\tightlist}{ 154 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 155 | 156 | \thispagestyle{plain} 157 | \begin{center} 158 | 159 | {\LARGE\textbf{Modern C++ Tutorial: C++11/14/17/20 On the Fly}} 160 | 161 | \vspace{1em} 162 | {\large Changkun Ou (hi@changkun.us)} 163 | 164 | \vspace{1ex} 165 | Last update: \today 166 | 167 | \vspace{1ex} 168 | \textbf{Notice} 169 | 170 | \noindent The content in this PDF file may outdated, please check \href{https://changkun.de/modern-cpp}{our website} or \href{https://github.com/changkun/modern-cpp-tutorial}{GitHub repository} for the latest book updates. 171 | 172 | \vspace{1em} 173 | \textbf{\large License} 174 | 175 | \noindent This work was written by \href{https://github.com/changkun}{Ou Changkun} and licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. \texttt{\small http://creativecommons.org/licenses/by-nc-nd/4.0/} 176 | 177 | \vspace{5em} 178 | \includegraphics{../../assets/cover-2nd-en} 179 | 180 | \end{center} 181 | 182 | $for(include-before)$ 183 | $include-before$ 184 | 185 | $endfor$ 186 | 187 | { 188 | \newpage 189 | \hypersetup{linkcolor=black} 190 | \setcounter{tocdepth}{3} 191 | \tableofcontents 192 | } 193 | \newpage 194 | 195 | $body$ 196 | 197 | $if(natbib)$ 198 | $if(biblio-files)$ 199 | $if(biblio-title)$ 200 | $if(book-class)$ 201 | \renewcommand\bibname{$biblio-title$} 202 | $else$ 203 | \renewcommand\refname{$biblio-title$} 204 | $endif$ 205 | $endif$ 206 | \bibliography{$biblio-files$} 207 | 208 | $endif$ 209 | $endif$ 210 | $if(biblatex)$ 211 | \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ 212 | 213 | $endif$ 214 | $for(include-after)$ 215 | $include-after$ 216 | 217 | $endfor$ 218 | \end{document} -------------------------------------------------------------------------------- /github_code/pdf/zh-cn/Makefile: -------------------------------------------------------------------------------- 1 | title = '现代 C++ 教程:高速上手 C++11/14/17/20' 2 | filename = 'modern-cpp-tutorial' 3 | outputname='modern-cpp-tutorial' 4 | revision = $(shell git describe --always --tags) 5 | 6 | all: revision pdf 7 | 8 | revision: 9 | @echo '% Autogenerated, do not edit' > revision.tex 10 | @echo '\\newcommand{\\revision}{'$(revision)'}' >> revision.tex 11 | 12 | pdf: markdown 13 | @echo "Compiling PDF file..." 14 | pandoc -f markdown+smart -s $(filename).md -o $(filename).pdf \ 15 | --title-prefix $(title) \ 16 | --template=meta/template.tex \ 17 | --pdf-engine=`which xelatex` 18 | @echo "Done." 19 | rm *.md revision.tex 20 | 21 | markdown: 22 | @echo "Copy markdown files..." 23 | cp -r ../../book/zh-cn/* . 24 | @echo "Aggregating markdown files..." 25 | python3 aggregator.py 26 | 27 | clean: 28 | rm -rf revision.tex *.md 29 | 30 | .PHONY: markdown pdf clean -------------------------------------------------------------------------------- /github_code/pdf/zh-cn/aggregator.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # author: changkun 3 | 4 | import os, io 5 | 6 | chapters = ['00-preface.md', '01-intro.md', '02-usability.md', '03-runtime.md', '04-containers.md', '05-pointers.md', '06-regex.md', '07-thread.md', '08-filesystem.md', '09-others.md', '10-cpp20.md', 'appendix1.md', 'appendix2.md'] 7 | 8 | ignores = ['TOC', '返回目录', '许可', 'license'] 9 | 10 | head = """--- 11 | title: "现代 C++ 教程:高速上手 C++11/14/17/20" 12 | author: 欧长坤 13 | copyright: cc-by-nc-nd 4.0 14 | --- 15 | """ 16 | 17 | with io.open('modern-cpp-tutorial.md', 'w', encoding='utf8') as outfile: 18 | outfile.write(head) 19 | for chapter in chapters: 20 | if os.path.isfile(chapter): 21 | with open(chapter) as ch: 22 | outfile.write('\n') 23 | for line in ch: 24 | if any(keyword in line for keyword in ignores): 25 | continue 26 | else: 27 | outfile.write(line) -------------------------------------------------------------------------------- /github_code/website/Makefile: -------------------------------------------------------------------------------- 1 | all: clean 2 | node install.js 3 | python3 filter.py 4 | cp ../assets/cover-2nd.png ./src/modern-cpp/assets/cover-2nd.png 5 | cp ../assets/cover-2nd-logo.png ./src/modern-cpp/assets/cover-2nd-logo.png 6 | cp ../assets/cover-2nd-en.png ./src/modern-cpp/assets/cover-2nd-en.png 7 | cp ../assets/cover-2nd-en-logo.png ./src/modern-cpp/assets/cover-2nd-en-logo.png 8 | cp ../assets/alipay.jpg ./src/modern-cpp/assets/alipay.jpg 9 | cp ../assets/wechat.jpg ./src/modern-cpp/assets/wechat.jpg 10 | cp ../assets/donate.md ./src/modern-cpp/about/ 11 | cp ../assets/community.md ./src/modern-cpp/about/ 12 | cp -r ../assets/figures ./src/modern-cpp/assets/figures 13 | cp -r ../exercises ./src/modern-cpp/ 14 | cp -r ../code ./src/modern-cpp/ 15 | npx hexo generate 16 | mv public/index.html public/modern-cpp/index.html 17 | s: all 18 | node_modules/serve/bin/serve.js ./public 19 | clean: 20 | rm -rf ./src/modern-cpp/assets/cover-2nd.png \ 21 | ./src/modern-cpp/assets/cover-2nd-en.png \ 22 | ./src/modern-cpp/assets/cover-2nd-logo.png \ 23 | ./src/modern-cpp/assets/cover-2nd-en-logo.png \ 24 | ./src/modern-cpp/assets/figures \ 25 | ./src/modern-cpp/assets/alipay.jpg \ 26 | ./src/modern-cpp/assets/wechat.jpg \ 27 | ./src/modern-cpp/about/donate.md \ 28 | ./src/modern-cpp/about/community.md \ 29 | ./src/modern-cpp/code \ 30 | ./src/modern-cpp/exercises \ 31 | public db.json src/modern-cpp/zh-cn src/modern-cpp/en-us 32 | -------------------------------------------------------------------------------- /github_code/website/README.md: -------------------------------------------------------------------------------- 1 | # changkun.de/modern-cpp 2 | 3 | Welcome to Modern C++ Tutorial! This site is built with [hexo](http://hexo.io/). Site content was written in Markdown format located in `../book`. And all static files will be built into `./public`, which is served by a nginx server at [changkun.de](https://changkun.de). 4 | 5 | ## Requirements 6 | 7 | - node.js 8 | - npm 9 | 10 | ## Developing 11 | 12 | Start from the terminal: 13 | 14 | ``` 15 | $ make # build 16 | $ make s # start serve 17 | ``` 18 | -------------------------------------------------------------------------------- /github_code/website/_config.yml: -------------------------------------------------------------------------------- 1 | # Site Configuration 2 | title: "现代 C++ 教程: 高速上手 C++ 11/14/17/20" 3 | subtitle: C++ 11/14/17/20 On the Fly 4 | description: "欧长坤" 5 | author: 欧长坤 6 | email: hi[at]changkun.us 7 | language: zh-CN 8 | 9 | # URL 10 | url: https://changkun.de/modern-cpp/ 11 | root: / 12 | permalink: :year/:month/:day/:title/ 13 | code_dir: downloads/code 14 | 15 | # Directory 16 | source_dir: src 17 | public_dir: public 18 | 19 | # Writing 20 | new_post_name: :title.md # File name of new posts 21 | default_layout: post 22 | auto_spacing: false # Add spaces between asian characters and western characters 23 | titlecase: false # Transform title into titlecase 24 | external_link: true # Open external links in new tab 25 | max_open_file: 100 26 | multi_thread: true 27 | filename_case: 0 28 | render_drafts: false 29 | post_asset_folder: false 30 | highlight: 31 | enable: true 32 | line_number: false 33 | tab_replace: 34 | toc: 35 | maxdepth: 3 36 | class: toc 37 | slugify: transliteration 38 | decodeEntities: false 39 | anchor: 40 | position: after 41 | symbol: '#' 42 | style: header-anchor 43 | image_caption: 44 | enable: true 45 | 46 | # Date / Time format 47 | ## Hexo uses Moment.js to parse and display date 48 | ## You can customize the date format as defined in 49 | ## http://momentjs.com/docs/#/displaying/format/ 50 | date_format: MMM D YYYY 51 | time_format: H:mm:ss 52 | 53 | # Pagination 54 | ## Set per_page to 0 to disable pagination 55 | per_page: 10 56 | pagination_dir: page 57 | 58 | # Extensions 59 | theme: moderncpp 60 | exclude_generator: 61 | 62 | # Markdown 63 | ## https://github.com/chjj/marked 64 | marked: 65 | gfm: true 66 | pedantic: false 67 | sanitize: false 68 | tables: true 69 | breaks: false 70 | smartLists: true 71 | smartypants: false -------------------------------------------------------------------------------- /github_code/website/filter.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # author: changkun 3 | import os 4 | import re 5 | 6 | source_dir = [ 7 | '../book/zh-cn/', 8 | '../book/en-us/' 9 | ] 10 | 11 | destination_dir = [ 12 | './src/modern-cpp/zh-cn/', 13 | './src/modern-cpp/en-us/' 14 | ] 15 | 16 | chapters = ['00-preface.md', '01-intro.md', '02-usability.md', '03-runtime.md', '04-containers.md', '05-pointers.md', '06-regex.md', '07-thread.md', '08-filesystem.md', '09-others.md', '10-cpp20.md', 'appendix1.md', 'appendix2.md'] 17 | 18 | ignores = ['TOC', '返回目录', '许可', 'license', 'Table of Content', 'License'] 19 | 20 | for index, source in enumerate(source_dir): 21 | for chapter in chapters: 22 | dst_filepath = destination_dir[index] + chapter[:-3] 23 | os.makedirs(dst_filepath) 24 | print(dst_filepath) 25 | print(dst_filepath + '/index.md') 26 | with open(source+chapter, 'r', encoding='utf-8') as source_file: 27 | with open(dst_filepath + '/index.md', 'w', encoding='utf-8') as output_file: 28 | for line in source_file: 29 | if any(keyword in line for keyword in ignores): 30 | continue 31 | else: 32 | output_file.write(re.sub(r'(./)(.*?)(.md)', r'../\2/index.html', line)) 33 | -------------------------------------------------------------------------------- /github_code/website/install.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var execSync = require('child_process').execSync 3 | var deps = require('./package.json').dependencies 4 | var depFolders = Object.keys(deps) 5 | 6 | for (var depFolder in deps) { 7 | if (!fs.existsSync('./node_modules/' + depFolder)) { 8 | console.log('Dependency "' + depFolder + '" is NOT installed - installing now...') 9 | execSync('npm install') 10 | process.exit(0) 11 | } 12 | } 13 | 14 | console.log('All dependencies are already installed.') 15 | -------------------------------------------------------------------------------- /github_code/website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modern-cpp", 3 | "version": "2.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "4.2.1" 7 | }, 8 | "dependencies": { 9 | "hexo-generator-index": "^0.2.1", 10 | "hexo-image-caption": "^0.1.1", 11 | "hexo-renderer-ejs": "^0.3.1", 12 | "hexo-renderer-marked": "^1.0.1", 13 | "hexo-renderer-stylus": "^0.3.3" 14 | }, 15 | "devDependencies": { 16 | "hexo": "^4.2.1", 17 | "serve": "^11.3.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /github_code/website/src/_posts/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | index: true 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/about/ack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 致谢 3 | type: about 4 | order: 4 5 | --- 6 | 7 | ## Acknowledgements 8 | 9 | This book was originally written in Chinese by [Changkun Ou](https://changkun.de). 10 | 11 | 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). 12 | 13 | The author is grateful to all contributors, including but not limited to [Contributors](https://github.com/changkun/modern-cpp-tutorial/graphs/contributors). 14 | 15 |

This project is also supported by:

16 |

17 | 18 | 19 | 20 |

21 | 22 | ## 致谢 23 | 24 | 笔者时间和水平有限,如果读者发现书中内容的错误,欢迎提 [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)。 25 | 26 |

本项目还由以下产品提供赞助支持:

27 |

28 | 29 | 30 | 31 |

-------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/about/copyright.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 版权声明 3 | type: about 4 | order: 3 5 | --- 6 | 7 | 知识共享许可协议 8 | 9 | 本书系[欧长坤](https://github.com/changkun)著,采用[知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议](http://creativecommons.org/licenses/by-nc-nd/4.0/)许可。项目中代码使用 [MIT](https://opensource.org/licenses/MIT) 协议开源。 -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/website/src/modern-cpp/assets/check.png -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/website/src/modern-cpp/assets/down.png -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/feed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/website/src/modern-cpp/assets/feed.png -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/lang/cn.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | chi 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/lang/de.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | deu 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/lang/en.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | ebr 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/website/src/modern-cpp/assets/menu.png -------------------------------------------------------------------------------- /github_code/website/src/modern-cpp/assets/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/github_code/website/src/modern-cpp/assets/search.png -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/_config.yml: -------------------------------------------------------------------------------- 1 | site_description: "Modern C++ Tutorial | C++ 11/14/17/20 On the Fly | 现代 C++ 教程 | 高速上手 C++11/14/17/20" 2 | google_analytics: 3 | root_domain: changkun.de/modern-cpp 4 | moderncpp_version: 2.0.0 5 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/index.ejs: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |
15 |
16 | "> 17 |
18 |

欧长坤 著

19 |

20 | 现代 C++ 教程
21 |

22 |

高速上手 C++ 11/14/17/20

23 |

第二版

24 |

25 | ">🇨🇳 在线阅读 26 | ">🇨🇳 下载 27 |

28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 | "> 36 |
37 |

Changkun Ou

38 |

39 | Modern C++ Tutorial 40 |

41 |

C++ 11/14/17/20 On the Fly

42 |

SECOND EDITION

43 |

44 | ">🇬🇧 Read Online 45 | ">🇬🇧 Download 46 |

47 |
48 |
49 |
50 | 51 | 61 | 62 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/layout.ejs: -------------------------------------------------------------------------------- 1 | <% var isIndex = page.path === 'index.html' %> 2 | 3 | 4 | 5 | 6 | <%- page.title ? page.title : '' %> 现代 C++ 教程: 高速上手 C++ 11/14/17/20 - Modern C++ Tutorial: C++ 11/14/17/20 On the Fly 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 22 | 23 | 24 | 25 | 26 | 27 | <%- css(isIndex ? 'modern-cpp/css/index' : 'modern-cpp/css/page') %> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | <% if (page.type == 'book-en-us') { %> 36 |
> 37 | 38 | 39 |
40 | <% } else {%> 41 |
> 42 | 43 | 44 |
45 | <% } %> 46 | <%- partial('partials/header') %> 47 | <% if (!isIndex) { %> 48 |
49 | <%- body %> 50 |
51 | <% } else { %> 52 | <%- body %> 53 | <% } %> 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/page.ejs: -------------------------------------------------------------------------------- 1 | <% if (page.type) { %> 2 | <%- partial('partials/sidebar', { type: page.type, index: page.index }) %> 3 | <% } else { %> 4 | 13 | <% } %> 14 |
15 | <%- page.content %> 16 | 24 | 25 | <% if (page.type == 'book-en-us') { %> 26 | 35 | <% } else {%> 36 | 45 | <% } %> 46 | 47 | 48 |
49 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/partials/header.ejs: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/partials/main_menu.ejs: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 40 | 41 | 44 | 45 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/partials/main_menu_en.ejs: -------------------------------------------------------------------------------- 1 | 13 | 14 | 25 | 26 | 40 | 41 | 44 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/partials/sidebar.ejs: -------------------------------------------------------------------------------- 1 | 42 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/partials/toc.ejs: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/layout/post.ejs: -------------------------------------------------------------------------------- 1 | 21 |
22 |

<%- page.title %>

23 |

<%- page.date.format('MMM D[,] YYYY') %>

24 | <%- page.content %> 25 |
26 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_animations.styl: -------------------------------------------------------------------------------- 1 | .rotating-clockwise 2 | animation: 3s rotating-clockwise linear infinite 3 | 4 | i.rotating-clockwise 5 | display: inline-block 6 | animation-duration: 2s 7 | 8 | @keyframes rotating-clockwise 9 | from 10 | transform: rotate(0) 11 | to 12 | transform: rotate(360deg) 13 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_common.styl: -------------------------------------------------------------------------------- 1 | @import "_settings" 2 | @import "_syntax" 3 | 4 | body 5 | font-family: $body-font 6 | font-size: $body-font-size 7 | -webkit-font-smoothing: antialiased 8 | -moz-osx-font-smoothing: grayscale 9 | color: $medium 10 | background-color: white 11 | margin: 0 12 | &.docs 13 | padding-top: $header-height 14 | 15 | @media screen and (max-width: 900px) 16 | body.docs 17 | padding-top: 0 18 | 19 | a 20 | text-decoration: none 21 | color: $medium 22 | 23 | img 24 | border: none 25 | 26 | h1, h2, h3, h4, strong 27 | font-weight: 600 28 | color: $dark 29 | 30 | code, pre 31 | font-family: $code-font 32 | font-size: $code-font-size 33 | background-color: $codebg 34 | -webkit-font-smoothing: initial 35 | -moz-osx-font-smoothing: initial 36 | 37 | code 38 | color: #e96900 39 | padding: 3px 5px 40 | margin: 0 2px 41 | border-radius: 2px 42 | white-space: nowrap 43 | 44 | em 45 | color: $light 46 | 47 | p 48 | word-spacing: 0.05em 49 | 50 | a.button 51 | padding: 0.75em 2em 52 | border-radius: 2em 53 | display: inline-block 54 | color: #fff 55 | background-color: lighten($theme, 8%) 56 | transition: all .15s ease 57 | box-sizing: border-box 58 | border: 1px solid lighten($theme, 8%) 59 | width: 200px; 60 | &.white 61 | background-color: #fff 62 | color: $theme 63 | &.download 64 | background-color: $theme 65 | color: #fff 66 | a.button:hover 67 | background-color: $theme 68 | color: #fff 69 | 70 | .highlight 71 | overflow-x: auto 72 | background-color: $codebg 73 | padding: .4em 0 0 74 | line-height: 1.1em 75 | border-radius: $radius 76 | position: relative 77 | table, tr, td 78 | width: 100% 79 | border-collapse: collapse 80 | padding: 0 81 | margin: 0 82 | .gutter 83 | width: 1.5em 84 | .code 85 | $code-line-height = 1.5em 86 | pre 87 | padding: 1.2em 1.4em 88 | line-height: $code-line-height 89 | margin: 0 90 | .line 91 | min-height: $code-line-height 92 | &.html, &.js, &.bash, &.css 93 | .code:before 94 | position: absolute 95 | top: 0 96 | right: 0 97 | color: #ccc 98 | text-align: right 99 | font-size: .75em 100 | padding: 5px 10px 0 101 | line-height: 15px 102 | height: 15px 103 | font-weight: 600 104 | &.html .code:before 105 | content: "HTML" 106 | &.js .code:before 107 | content: "JS" 108 | &.bash .code:before 109 | content: "Shell" 110 | &.css .code:before 111 | content: "CSS" 112 | 113 | #main 114 | position: relative 115 | z-index: 1 116 | padding: 0 60px 30px 117 | overflow-x: hidden 118 | 119 | #nav 120 | .nav-link 121 | color: #fff 122 | // cursor: pointer 123 | .nav-dropdown-container 124 | .nav-link 125 | &:hover:not(.current) 126 | border-bottom: none 127 | &:hover 128 | .nav-dropdown 129 | display: block 130 | &.language, &.ecosystem 131 | margin-left: 20px 132 | .arrow 133 | pointer-events: none 134 | .nav-dropdown 135 | display: none 136 | box-sizing: border-box 137 | max-height: "calc(100vh - %s)" % $header-height 138 | overflow-y: auto 139 | position: absolute 140 | top: 100% 141 | right: -15px 142 | background-color: $theme 143 | padding: 10px 0 144 | border: 1px solid #fff 145 | border-bottom-color: $theme 146 | text-align: left 147 | border-radius: 4px 148 | white-space: nowrap 149 | li 150 | line-height: 1.8em 151 | margin: 0 152 | display: block 153 | > ul 154 | padding-left: 0 155 | &:first-child 156 | h4 157 | margin-top: 0 158 | padding-top: 0 159 | border-top: 0 160 | a, h4 161 | padding: 0 24px 0 20px 162 | h4 163 | margin: .45em 0 0 164 | padding-top: .45em 165 | border-top: 1px solid #eee 166 | a 167 | color: #fff 168 | font-size: .9em 169 | display: block 170 | &:hover 171 | color: $yellow 172 | .arrow 173 | display: inline-block 174 | vertical-align: middle 175 | margin-top: -1px 176 | margin-left: 6px 177 | margin-right: -14px 178 | width: 0 179 | height: 0 180 | border-left: 4px solid transparent 181 | border-right: 4px solid transparent 182 | border-top: 5px solid #fff 183 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_header.styl: -------------------------------------------------------------------------------- 1 | $header-height = 40px 2 | 3 | #header 4 | background-color: $theme 5 | height: $header-height 6 | padding: $heading-padding-vertical 60px 7 | position: relative 8 | z-index: 2 9 | 10 | body.docs 11 | #header 12 | position: fixed 13 | width: 100% 14 | top: 0 15 | left: 0 16 | right: 0 17 | bottom: 0 18 | padding: 10px 19 | #nav 20 | position: fixed 21 | #logo 22 | margin-left: 20px 23 | margin-right: 20px 24 | #logo span 25 | font-size: 1.2em 26 | #logo img 27 | margin-top: -6px 28 | #mobile-bar::before 29 | content: attr(data-bg-text) 30 | text-align: center 31 | color: #fff 32 | display: block 33 | line-height: 1 34 | position: absolute 35 | margin-top: 12px 36 | font-size: 2em 37 | width: 100% 38 | 39 | #nav 40 | list-style-type: none 41 | margin: 0 42 | padding: 0 43 | position: absolute 44 | right: 30px 45 | top: $heading-padding-vertical 46 | height: $header-height 47 | line-height: $header-height 48 | .break 49 | display: none 50 | li 51 | display: inline-block 52 | position: relative 53 | margin: 0 .6em 54 | margin-right: 30px 55 | 56 | .nav-dropdown 57 | .nav-link 58 | &:hover, &.current 59 | border-bottom: none 60 | &.current 61 | &::after 62 | content: "" 63 | width: 0 64 | height: 0 65 | border-left: 5px solid $theme 66 | border-top: 3px solid transparent 67 | border-bottom: 3px solid transparent 68 | position: absolute 69 | top: 50% 70 | margin-top: -4px 71 | left: 8px 72 | 73 | .nav-link 74 | padding-bottom: 3px 75 | &:hover, &.current 76 | border-bottom: 3px solid $theme 77 | &.team 78 | margin-left: 10px 79 | 80 | .new-label 81 | position: absolute 82 | top: 3px 83 | left: 110% 84 | background-color: $theme 85 | color: #fff 86 | line-height: 16px 87 | height: 16px 88 | font-size: 9px 89 | font-weight: bold 90 | font-family: $code-font 91 | padding: 1px 4px 0 6px 92 | border-radius: 4px 93 | 94 | #logo 95 | display: inline-block 96 | font-size: 1.5em 97 | line-height: $header-height 98 | color: #fff 99 | font-family: $logo-font 100 | font-weight: 500 101 | img 102 | vertical-align: middle 103 | margin-right: 6px 104 | height: $header-height 105 | border-radius: 2px; 106 | box-shadow: 0 20px 80px rgba(0, 0, 0, 0.4); 107 | overflow:hidden; 108 | #mobile-bar::before 109 | content: attr(data-bg-text) 110 | text-align: center 111 | color: #fff 112 | display: block 113 | line-height: 1 114 | position: absolute 115 | margin-top: 12px 116 | font-size: 2em 117 | width: 100% 118 | #mobile-bar 119 | position: fixed 120 | top: 0 121 | left: 0 122 | width: 100% 123 | height: 50px 124 | background-color: $theme; 125 | z-index: 100 126 | display: none 127 | box-shadow: 0 0 2px rgba(0,0,0,.25) 128 | font-size: 0.9em 129 | .menu-button 130 | position: absolute 131 | width: 24px 132 | height: 24px 133 | top: 14px 134 | left: 12px 135 | background: url(../assets/menu.png) center center no-repeat 136 | background-size: 24px 137 | .logo 138 | position: absolute 139 | width: 25px 140 | height: 30px 141 | background: url(../assets/cover-2nd-en-logo.png) center center no-repeat 142 | background-size: auto 100% 143 | top: 12px 144 | right: 12px 145 | margin-left: -15px 146 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_settings.styl: -------------------------------------------------------------------------------- 1 | // font faces 2 | $body-font = "Source Sans Pro", "Helvetica Neue", Arial, sans-serif 3 | $logo-font = "Dosis", "Source Sans Pro", "Helvetica Neue", Arial, sans-serif 4 | $code-font = "Roboto Mono", Monaco, courier, monospace 5 | 6 | // font sizes 7 | $body-font-size = 15px 8 | $code-font-size = .8em 9 | 10 | // colors 11 | $theme = #7e2d36 12 | $orange = #ec9325 13 | $dark = #2c3e50 14 | $medium = #34495e 15 | $light = #7f8c8d 16 | $green = #42b983 17 | $border = #dddddd 18 | $codebg = #f8f8f8 19 | $red = #ff6666 20 | $info = #1C90F3 21 | $yellow = yellow 22 | 23 | $radius = 2px 24 | $content-padding-top = 30px 25 | $header-inner-height = 41px 26 | $heading-padding-vertical = 10px 27 | $header-height = $header-inner-height + $heading-padding-vertical * 2 28 | $mobile-header-height = 40px 29 | $heading-link-padding-top = $header-height + $content-padding-top 30 | $mobile-heading-link-padding-top = $mobile-header-height + $content-padding-top 31 | $h2-margin-top = 45px 32 | $h3-margin-top = 52px 33 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_sidebar.styl: -------------------------------------------------------------------------------- 1 | @import "_settings" 2 | 3 | .sidebar 4 | position: fixed 5 | z-index: 10 6 | top: $header-height 7 | left: 0 8 | bottom: 0 9 | overflow-x: hidden 10 | overflow-y: auto 11 | -webkit-overflow-scrolling: touch 12 | -ms-overflow-style: none 13 | h2 14 | margin-top: .2em 15 | ul 16 | list-style-type: none 17 | margin: 0 18 | line-height: 1.5em 19 | padding-left: 1em 20 | li 21 | margin-top: .5em 22 | .sidebar-inner 23 | width: 260px 24 | padding: $content-padding-top + 10px 20px 60px 60px 25 | .version-select 26 | vertical-align: middle 27 | margin-left: 5px 28 | .menu-root 29 | padding-left: 0 30 | .menu-sub 31 | font-size: .85em 32 | .sidebar-link 33 | color: $light 34 | &.current 35 | font-weight: 600 36 | color: $theme 37 | &.new 38 | &:after 39 | content: "NEW" 40 | display: inline-block 41 | font-size: 10px 42 | font-weight: 600 43 | color: #fff 44 | background-color: $theme 45 | line-height: 14px 46 | padding: 0 4px 47 | border-radius: 3px 48 | margin-left: 5px 49 | vertical-align: middle 50 | position: relative 51 | top: -1px 52 | &:hover 53 | border-bottom: 2px solid $theme 54 | .section-link 55 | &.active 56 | font-weight: bold 57 | color: $theme 58 | .main-menu 59 | margin-bottom: 20px 60 | display: none 61 | padding-left: 0 62 | .nav-dropdown 63 | h4 64 | font-weight: normal 65 | margin: 0 66 | 67 | @media screen and (max-width: 900px) 68 | .sidebar 69 | position: fixed 70 | z-index: 10 71 | background-color: #f9f9f9 72 | height: 100% 73 | top: 0 74 | left: 0 75 | box-shadow: 0 0 10px rgba(0,0,0,.2) 76 | transition: all .4s cubic-bezier(0.4, 0, 0, 1) 77 | -webkit-transform: translate(-280px, 0) 78 | transform: translate(-280px, 0) 79 | .sidebar-inner 80 | padding: 50px 10px 10px 20px 81 | box-sizing: border-box 82 | .sidebar-inner-index 83 | padding: 80px 40px 10px 30px 84 | box-sizing: border-box 85 | .main-menu 86 | display: block 87 | &.open 88 | -webkit-transform: translate(0, 0) 89 | transform: translate(0, 0) 90 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/_syntax.styl: -------------------------------------------------------------------------------- 1 | .gutter pre 2 | color: #999 3 | 4 | pre 5 | color: #525252 6 | .function .keyword, 7 | .constant 8 | color: #0092db 9 | .keyword, 10 | .attribute 11 | color: #e96900 12 | .number, 13 | .literal 14 | color: #AE81FF 15 | .tag, 16 | .tag .title, 17 | .change, 18 | .winutils, 19 | .flow, 20 | .lisp .title, 21 | .clojure .built_in, 22 | .nginx .title, 23 | .tex .special 24 | color: #2973b7 25 | .class .title 26 | color: #1C90F3 27 | .symbol, 28 | .symbol .string, 29 | .value, 30 | .regexp 31 | color: $theme 32 | .title 33 | color: #7e2d36 34 | .tag .value, 35 | .string, 36 | .subst, 37 | .haskell .type, 38 | .preprocessor, 39 | .ruby .class .parent, 40 | .built_in, 41 | .sql .aggregate, 42 | .django .template_tag, 43 | .django .variable, 44 | .smalltalk .class, 45 | .javadoc, 46 | .django .filter .argument, 47 | .smalltalk .localvars, 48 | .smalltalk .array, 49 | .attr_selector, 50 | .pseudo, 51 | .addition, 52 | .stream, 53 | .envvar, 54 | .apache .tag, 55 | .apache .cbracket, 56 | .tex .command, 57 | .prompt 58 | color: $theme 59 | .comment, 60 | .java .annotation, 61 | .python .decorator, 62 | .template_comment, 63 | .pi, 64 | .doctype, 65 | .deletion, 66 | .shebang, 67 | .apache .sqbracket, 68 | .tex .formula 69 | color: #b3b3b3 70 | .coffeescript .javascript, 71 | .javascript .xml, 72 | .tex .formula, 73 | .xml .javascript, 74 | .xml .vbscript, 75 | .xml .css, 76 | .xml .cdata 77 | opacity: 0.5 78 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/index.styl: -------------------------------------------------------------------------------- 1 | @import "_common" 2 | @import "_header" 3 | @import "_sidebar" 4 | 5 | $width = 900px 6 | 7 | body 8 | background-color: #fff 9 | margin-bottom: 200px 10 | #logo 11 | span 12 | font-size: 1.2em 13 | img 14 | display: none 15 | 16 | .sidebar 17 | display: none 18 | 19 | #mobile-bar 20 | &.top 21 | background-color: $theme 22 | box-shadow: none 23 | .logo 24 | display: none 25 | 26 | #hero 27 | padding: 100px 40px 40px 200px 28 | background-color: #fff 29 | .inner 30 | max-width: $width 31 | margin: 0 auto 32 | .left, .right 33 | display: inline-block 34 | vertical-align: top 35 | .left 36 | width: 45% 37 | .right 38 | width: 55% 39 | .hero-logo 40 | width: 290px 41 | float: right 42 | margin-right: 60px 43 | border-radius: 5px 44 | box-shadow: 0 20px 80px rgba(0, 0, 0, 0.4) 45 | h1 46 | text-transform: uppercase 47 | font-weight: 500 48 | margin: 10px 0px 49 | margin-top: 0px 50 | font-size: 3.2em 51 | h2 52 | text-transform: uppercase 53 | font-weight: 300 54 | font-size: 2.4em 55 | margin: 0 0 10px 56 | h4 57 | font-style: oblique 58 | font-weight: 200 59 | margin-bottom: 0px 60 | font-size: 2em 61 | .button 62 | margin: 1em 0 63 | font-size: 1.05em 64 | font-weight: 600 65 | letter-spacing: .1em 66 | min-width: 8em 67 | text-align: center 68 | &:first-child 69 | margin-right: 1em 70 | .social-buttons 71 | list-style-type: none 72 | padding: 0 73 | li 74 | display: inline-block 75 | vertical-align: middle 76 | margin-right: 15px 77 | 78 | #highlights 79 | background-color: #fff 80 | padding-bottom: 70px 81 | .inner 82 | max-width: $width 83 | margin: 0 auto 84 | text-align: center 85 | .point 86 | width: 33% 87 | display: inline-block 88 | vertical-align: top 89 | box-sizing: border-box 90 | padding: 0 2em 91 | h2 92 | color: $theme 93 | font-size: 1.5em 94 | font-weight: 400 95 | margin: 0 96 | padding: .5em 0 97 | p 98 | color: $light 99 | 100 | #footer 101 | background-color: #1e2318 102 | bottom: 0 103 | padding: 10px 0 104 | position: fixed 105 | width: 100% 106 | color: #fff 107 | text-align: center 108 | a 109 | font-weight: 700 110 | color: #fff 111 | 112 | @media screen and (max-width: $width) 113 | body 114 | -webkit-text-size-adjust: none 115 | font-size: 14px 116 | margin-bottom: 200px 117 | .sidebar 118 | display: block 119 | #header 120 | display: none 121 | #mobile-bar 122 | display: block 123 | #hero 124 | padding: 70px 40px 50px 125 | .hero-logo 126 | float: none 127 | margin: 30px 0 30px 128 | width: 200px 129 | .left, .right 130 | text-align: center 131 | width: 100% 132 | h1 133 | text-transform: capitalize 134 | font-size: 2.0em 135 | display: block 136 | h2 137 | font-size: 1.0em 138 | .button 139 | font-size: .9em 140 | h4 141 | font-size: 0.9em 142 | #highlights 143 | .point 144 | display: block 145 | margin: 0 auto 146 | width: 300px 147 | padding: 0 40px 30px 148 | &:before 149 | content: "—" 150 | color: $theme 151 | -------------------------------------------------------------------------------- /github_code/website/themes/moderncpp/source/modern-cpp/css/page.styl: -------------------------------------------------------------------------------- 1 | @import "_common" 2 | @import "_animations" 3 | @import "_header" 4 | @import "_sidebar" 5 | 6 | #header 7 | box-shadow: 0 0 1px rgba(0,0,0,.25) 8 | transition: background-color .3s ease-in-out 9 | 10 | .image-caption 11 | display: table; 12 | margin: 0 auto; 13 | color: #7f8c8d; 14 | margin-top: 10px; 15 | 16 | .content 17 | position: relative 18 | padding: 2.2em 0 19 | max-width: 600px 20 | margin: 0 auto 21 | padding-left: 50px 22 | &.api 23 | > a:first-of-type > h2 24 | margin-top: 0 25 | padding-top: 0 26 | ul 27 | padding-left: 1.25em 28 | line-height: 1.4em 29 | ul, p:not(.tip) 30 | padding-bottom: 0 31 | margin: 1.2em 0 32 | a.button 33 | font-size: .9em 34 | color: #fff 35 | margin: .2em 0 36 | width: 180px 37 | text-align: center 38 | padding: 12px 24px 39 | display: inline-block 40 | vertical-align: middle 41 | img 42 | max-width: 100% 43 | span.light 44 | color: $light 45 | span.info 46 | font-size: .85em 47 | display: inline-block 48 | vertical-align: middle 49 | width: 280px 50 | margin-left: 20px 51 | h1 52 | margin: 0 0 1em 53 | h2, h3 54 | &:before 55 | content: "" 56 | display: block 57 | margin-top: -1 * $heading-link-padding-top 58 | height: $heading-link-padding-top 59 | visibility: hidden 60 | h2 61 | margin: $h2-margin-top 0 .8em 62 | padding-bottom: .7em 63 | border-bottom: 1px solid $border 64 | z-index: -1 65 | h3 66 | margin: $h3-margin-top 0 1.2em 67 | position: relative 68 | z-index: -1 69 | &:after 70 | content: "#" 71 | color: $theme 72 | position: absolute 73 | left: -0.7em 74 | bottom: -2px 75 | font-size: 1.2em 76 | font-weight: bold 77 | figure 78 | margin: 1.2em 0 79 | p, ul, ol 80 | line-height: 1.6em 81 | // HACK: Create area underneath paragraphs 82 | // and lists that will be on top of heading 83 | // anchors, for easier text highlighting. 84 | margin: 1.2em 0 -1.2em 85 | padding-bottom: 1.2em 86 | position: relative 87 | z-index: 1 88 | ul, ol 89 | padding-left: 1.5em 90 | // FIX: Some link click targets are covered without this 91 | position: inherit 92 | a 93 | color: $theme 94 | font-weight: 600 95 | blockquote 96 | margin: 2em 0 97 | padding-left: 20px 98 | border-left: 4px solid $theme 99 | p 100 | font-weight: 600 101 | margin-left: 0 102 | margin-bottom: 0 103 | padding-bottom: 0 104 | iframe 105 | margin: 1em 0 106 | > table 107 | border-spacing: 0 108 | border-collapse: collapse 109 | margin: 1.2em auto 110 | padding: 0 111 | display: block 112 | overflow-x: auto 113 | td, th 114 | line-height: 1.5em 115 | padding: .4em .8em 116 | border: none 117 | border: 1px solid #ddd 118 | th 119 | font-weight: bold 120 | text-align: left 121 | th, tr:nth-child(2n) 122 | background-color: #f8f8f8 123 | code 124 | background-color: #efefef 125 | p 126 | &.tip, &.success 127 | padding: 12px 24px 12px 30px 128 | margin: 2em 0 129 | border-left-width: 4px 130 | border-left-style: solid 131 | background-color: $codebg 132 | position: relative 133 | border-bottom-right-radius: $radius 134 | border-top-right-radius: $radius 135 | &:before 136 | position: absolute 137 | top: 14px 138 | left: -12px 139 | color: #fff 140 | width: 20px 141 | height: 20px 142 | border-radius: 100% 143 | text-align: center 144 | line-height: 20px 145 | font-weight: bold 146 | font-family: $logo-font 147 | font-size: 14px 148 | code 149 | background-color: #efefef 150 | em 151 | color: $medium 152 | &.tip 153 | border-left-color: $red 154 | &:before 155 | content: "!" 156 | background-color: $red 157 | &.success 158 | border-left-color: $theme 159 | &:before 160 | content: "\f00c" 161 | font-family: FontAwesome 162 | background-color: $theme 163 | 164 | .guide-links 165 | margin-top: 2em 166 | margin-bottom: 2em 167 | height: 1em 168 | 169 | .footer 170 | color: $light 171 | margin-top: 2em 172 | padding-top: 2em 173 | border-top: 1px solid #e5e5e5 174 | font-size: .9em 175 | 176 | #main.fix-sidebar 177 | position: static 178 | .sidebar 179 | position: fixed 180 | 181 | @media screen and (min-width: 1590px) 182 | #header 183 | background-color: $theme 184 | 185 | @media screen and (max-width: 1300px) 186 | .content.with-sidebar 187 | margin-left: 290px 188 | #ad 189 | z-index: 1 190 | position: relative 191 | padding: 0 192 | bottom: 0 193 | right: 0 194 | float: right 195 | padding: 0 0 20px 30px 196 | 197 | @media screen and (max-width: 900px) 198 | body 199 | -webkit-text-size-adjust: none 200 | font-size: 14px 201 | #header 202 | display: none 203 | #logo 204 | display: none 205 | .nav-link 206 | padding-bottom: 1px 207 | &:hover, &.current 208 | border-bottom: 2px solid $theme 209 | #mobile-bar 210 | display: block 211 | #main 212 | padding: 2em 1.4em 0 213 | .highlight pre 214 | padding: 1.2em 1em 215 | .content 216 | padding-left 0 217 | &.with-sidebar 218 | margin: auto 219 | h2, h3 220 | &:before 221 | content: "" 222 | display: block 223 | margin-top: -1 * $mobile-heading-link-padding-top 224 | height: $mobile-heading-link-padding-top 225 | visibility: hidden 226 | .footer 227 | margin-left: 0 228 | text-align: center 229 | 230 | @media screen and (max-width: 560px) 231 | #downloads 232 | text-align: center 233 | margin-bottom: 25px 234 | .info 235 | margin-top: 5px 236 | margin-left: 0 237 | iframe 238 | margin: 0 !important 239 | -------------------------------------------------------------------------------- /modern-cpp-tutorial-en-us.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/modern-cpp-tutorial-en-us.pdf -------------------------------------------------------------------------------- /modern-cpp-tutorial-zh-cn.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jash-git/modern-cpp-tutorial/ac7c434850ec4dc046a1d8d6ca79d1dd787577c9/modern-cpp-tutorial-zh-cn.pdf --------------------------------------------------------------------------------