├── book ├── .gitignore ├── imgs │ ├── long-long.0.png │ ├── mcpp-standard-demo.gif │ └── mcpp-logo.svg ├── README.md ├── src │ ├── cpp11 │ │ ├── 01-default-and-delete.md │ │ ├── 13-long-long.md │ │ ├── 00-auto-and-decltype.md │ │ ├── 09-list-initialization.md │ │ └── 12-nullptr.md │ ├── fqa.md │ ├── SUMMARY.md │ ├── base │ │ └── chapter_0.md │ ├── changelog.md │ └── README.md ├── en │ ├── src │ │ ├── cpp11 │ │ │ └── 01-default-and-delete.md │ │ ├── fqa.md │ │ ├── SUMMARY.md │ │ ├── base │ │ │ └── chapter_0.md │ │ ├── changelog.md │ │ └── README.md │ └── book.toml ├── book.toml └── build.sh ├── dslings ├── cpp14 │ └── README.md ├── cpp17 │ └── README.md ├── cpp20 │ └── README.md ├── cpp23 │ └── README.md ├── en │ ├── xmake.lua │ ├── cpp11 │ │ ├── 01-default-and-delete-2.cpp │ │ ├── 08-literal-type-1.cpp │ │ ├── 14-type-alias-3.cpp │ │ ├── 01-default-and-delete-0.cpp │ │ ├── 09-list-initialization-1.cpp │ │ ├── 07-constexpr-0.cpp │ │ ├── 03-trailing-return-type.cpp │ │ ├── 00-auto-and-decltype-0.cpp │ │ ├── 00-auto-and-decltype-3.cpp │ │ ├── 00-auto-and-decltype-1.cpp │ │ ├── 06-scoped-enums-0.cpp │ │ ├── 02-final-and-override-1.cpp │ │ ├── 09-list-initialization-0.cpp │ │ ├── 02-final-and-override-0.cpp │ │ ├── 14-type-alias-0.cpp │ │ ├── 12-nullptr-1.cpp │ │ ├── 09-list-initialization-2.cpp │ │ ├── 13-long-long-1.cpp │ │ ├── 13-long-long-0.cpp │ │ ├── 14-type-alias-2.cpp │ │ ├── 01-default-and-delete-1.cpp │ │ ├── 12-nullptr-2.cpp │ │ ├── 00-auto-and-decltype-2.cpp │ │ ├── 12-nullptr-0.cpp │ │ ├── 14-type-alias-1.cpp │ │ ├── 08-literal-type-0.cpp │ │ ├── 04-rvalue-references.cpp │ │ ├── 00-auto-and-decltype-4.cpp │ │ ├── 09-list-initialization-3.cpp │ │ ├── 06-scoped-enums-1.cpp │ │ ├── 11-inherited-constructors-0.cpp │ │ ├── 07-constexpr-1.cpp │ │ ├── 05-move-semantics-0.cpp │ │ ├── 02-final-and-override-2.cpp │ │ ├── 11-inherited-constructors-2.cpp │ │ ├── 10-delegating-constructors-0.cpp │ │ ├── 10-delegating-constructors-1.cpp │ │ ├── 05-move-semantics-2.cpp │ │ ├── 11-inherited-constructors-1.cpp │ │ └── 05-move-semantics-1.cpp │ └── hello-mcpp.cpp ├── xmake.lua ├── cpp11 │ ├── 01-default-and-delete-2.cpp │ ├── 08-literal-type-1.cpp │ ├── 07-constexpr-0.cpp │ ├── 01-default-and-delete-0.cpp │ ├── 14-type-alias-3.cpp │ ├── 09-list-initialization-1.cpp │ ├── 06-scoped-enums-0.cpp │ ├── 03-trailing-return-type.cpp │ ├── 00-auto-and-decltype-0.cpp │ ├── 00-auto-and-decltype-3.cpp │ ├── 14-type-alias-0.cpp │ ├── 00-auto-and-decltype-1.cpp │ ├── 02-final-and-override-1.cpp │ ├── 09-list-initialization-0.cpp │ ├── 02-final-and-override-0.cpp │ ├── 12-nullptr-2.cpp │ ├── 13-long-long-0.cpp │ ├── 13-long-long-1.cpp │ ├── 09-list-initialization-2.cpp │ ├── 12-nullptr-1.cpp │ ├── 14-type-alias-2.cpp │ ├── 01-default-and-delete-1.cpp │ ├── 14-type-alias-1.cpp │ ├── 12-nullptr-0.cpp │ ├── 00-auto-and-decltype-2.cpp │ ├── 08-literal-type-0.cpp │ ├── 04-rvalue-references.cpp │ ├── 06-scoped-enums-1.cpp │ ├── 00-auto-and-decltype-4.cpp │ ├── 07-constexpr-1.cpp │ ├── 11-inherited-constructors-0.cpp │ ├── 05-move-semantics-0.cpp │ ├── 09-list-initialization-3.cpp │ ├── 02-final-and-override-2.cpp │ ├── 11-inherited-constructors-2.cpp │ ├── 10-delegating-constructors-0.cpp │ ├── 05-move-semantics-2.cpp │ ├── 10-delegating-constructors-1.cpp │ ├── 11-inherited-constructors-1.cpp │ └── 05-move-semantics-1.cpp ├── d2x │ ├── honly_logger.hpp │ ├── common.lua │ └── common.hpp └── hello-mcpp.cpp ├── videos ├── d2x │ ├── __init__.py │ ├── animations.py │ └── video.py └── README.md ├── .devcontainer ├── postCreate.sh └── devcontainer.json ├── .gitignore ├── .vscode └── settings.json ├── config.xlings ├── tools ├── update_upstream.sh └── update_upstream.bat ├── CLA.md ├── .github └── workflows │ └── online-ebook.yml ├── README.zh.md ├── README.zh.hant.md └── README.md /book/.gitignore: -------------------------------------------------------------------------------- 1 | book -------------------------------------------------------------------------------- /dslings/cpp14/README.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /dslings/cpp17/README.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /dslings/cpp20/README.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /dslings/cpp23/README.md: -------------------------------------------------------------------------------- 1 | # TODO -------------------------------------------------------------------------------- /videos/d2x/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.1.0" 2 | 3 | from .animations import * 4 | from .video import * -------------------------------------------------------------------------------- /book/imgs/long-long.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sunrisepeak/mcpp-standard/HEAD/book/imgs/long-long.0.png -------------------------------------------------------------------------------- /book/imgs/mcpp-standard-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sunrisepeak/mcpp-standard/HEAD/book/imgs/mcpp-standard-demo.gif -------------------------------------------------------------------------------- /book/README.md: -------------------------------------------------------------------------------- 1 | **现代C++标准(cppref)** 2 | 3 | - C++11: [中](https://zh.cppreference.com/w/cpp/11) / [En](https://en.cppreference.com/w/cpp/11) 4 | -------------------------------------------------------------------------------- /dslings/en/xmake.lua: -------------------------------------------------------------------------------- 1 | add_includedirs("..") 2 | 3 | target("00-0-hello-mcpp") 4 | set_languages("cxx11") 5 | add_files("hello-mcpp.cpp") 6 | 7 | includes("cpp11") 8 | -------------------------------------------------------------------------------- /book/src/cpp11/01-default-and-delete.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./01-default-and-delete.html 7 | [English]: ../en/cpp11/01-default-and-delete.html 8 | 9 | # ... -------------------------------------------------------------------------------- /book/src/fqa.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./fqa.html 7 | [English]: ../en/fqa.html 8 | 9 | # 常见问题 10 | 11 | 更多问题和反馈 -> [教程论坛交流版块](https://forum.d2learn.org/category/20) 12 | -------------------------------------------------------------------------------- /book/en/src/cpp11/01-default-and-delete.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ../../cpp11/01-default-and-delete.html 7 | [English]: ./01-default-and-delete.html 8 | 9 | # Defaulted and Deleted Functions 10 | -------------------------------------------------------------------------------- /book/en/src/fqa.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ../fqa.html 7 | [English]: ./fqa.html 8 | 9 | # Frequently Asked Questions 10 | 11 | More questions and feedback -> [Tutorial Forum Discussion Section](https://forum.d2learn.org/category/20) 12 | -------------------------------------------------------------------------------- /.devcontainer/postCreate.sh: -------------------------------------------------------------------------------- 1 | # postCreate.sh 2 | #!/usr/bin/env bash 3 | set -euo pipefail 4 | 5 | sudo apt-get update 6 | sudo apt-get install -y ncurses-bin libtinfo6 libncursesw6 curl ca-certificates git 7 | 8 | if ! command -v xlings >/dev/null 2>&1; then 9 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 10 | fi 11 | 12 | echo "xlings installed" -------------------------------------------------------------------------------- /book/book.toml: -------------------------------------------------------------------------------- 1 | # docs: https://rust-lang.github.io/mdBook 2 | [book] 3 | title = "mcpp-standard | 动手学现代C++核心语言特性" 4 | author = "sunrispeak" 5 | language = "zh" 6 | 7 | [build] 8 | build-dir = "book" 9 | 10 | [output.html] 11 | git-repository-url = "https://github.com/Sunrisepeak/mcpp-standard" 12 | 13 | [preprocessor.foo] 14 | # Add any additional configurations 15 | -------------------------------------------------------------------------------- /book/en/book.toml: -------------------------------------------------------------------------------- 1 | # docs: https://rust-lang.github.io/mdBook 2 | [book] 3 | title = "mcpp-standard | D2X - Modern C++ Core Language Features" 4 | author = "sunrispeak" 5 | language = "en" 6 | 7 | [build] 8 | build-dir = "../book/en" 9 | 10 | [output.html] 11 | git-repository-url = "https://github.com/Sunrisepeak/mcpp-standard" 12 | 13 | [preprocessor.foo] 14 | # Add any additional configurations 15 | -------------------------------------------------------------------------------- /book/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # srcirpt dir 4 | SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 5 | 6 | echo "[Top] - Building Chinese book..." 7 | cd "$SCRIPT_DIR" 8 | mdbook build 9 | 10 | echo "[Sub - 1] - Building English book..." 11 | cd "$SCRIPT_DIR" 12 | cd en && mdbook build 13 | 14 | echo "[imgs] - copy imgs to output directory..." 15 | cd "$SCRIPT_DIR" 16 | cp -r imgs book/ 17 | 18 | echo "Build completed." 19 | 20 | # python -m http.server --directory book/book 21 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcpp-standard (Codespaces)", 3 | "image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-24.04", 4 | "customizations": { 5 | "vscode": { 6 | "extensions": [ 7 | "ms-vscode.cpptools", 8 | "twxs.cmake", 9 | "ms-vscode.cmake-tools", 10 | "formulahendry.code-runner" 11 | ] 12 | } 13 | }, 14 | "remoteUser": "vscode", 15 | "postCreateCommand": "/bin/bash .devcontainer/postCreate.sh", 16 | "postAttachCommand": "xlings checker" 17 | } 18 | -------------------------------------------------------------------------------- /dslings/xmake.lua: -------------------------------------------------------------------------------- 1 | if is_host("windows") then 2 | set_encodings("source:utf-8", "target:utf-8") 3 | set_toolchains("gcc") 4 | add_ldflags("-static") 5 | end 6 | 7 | local lang = "en" 8 | if d2x and d2x.private and d2x.private.mcpp then 9 | lang = d2x.private.mcpp.lang or "en" 10 | end 11 | 12 | if lang == "zh" then 13 | add_includedirs(".") 14 | 15 | target("00-0-hello-mcpp") 16 | set_languages("cxx11") 17 | add_files("hello-mcpp.cpp") 18 | 19 | includes("cpp11") 20 | else 21 | includes("en") 22 | end 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Python 35 | __pycache__ 36 | 37 | # d2x project files 38 | .xlings 39 | .vscode 40 | .xmake 41 | .zed 42 | llm.config.xlings 43 | media 44 | build 45 | .cache/ 46 | dslings/compile_commands.json 47 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "C_Cpp.default.includePath": [ 3 | // local include path 4 | "${default}", 5 | "${workspaceFolder}", 6 | "${workspaceFolder}/dslings", 7 | ], 8 | 9 | "C_Cpp.files.exclude": { 10 | "**/.vscode": true, 11 | "**/build": true, 12 | "**/.xmake": true, 13 | "**/.xlings": true, 14 | "**/.DS_Store": true 15 | }, 16 | 17 | "files.autoSave": "afterDelay", // or "onFocusChange", "onWindowChange", "off" 18 | "files.autoSaveDelay": 1000, 19 | "files.associations": { 20 | "ostream": "cpp" 21 | } // Only relevant for "afterDelay", in milliseconds 22 | } -------------------------------------------------------------------------------- /book/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [README](./README.md) 4 | 5 | # 阅读准备 6 | 7 | - [序言](./base/chapter_0.md) 8 | - [使用说明](./base/chapter_1.md) 9 | 10 | # C++11核心语言特性 11 | 12 | - [auto和decltype - 类型自动推导](./cpp11/00-auto-and-decltype.md) 13 | - [...](./cpp11/01-default-and-delete.md) 14 | - [列表初始化](./cpp11/09-list-initialization.md) 15 | - [委托构造函数](./cpp11/10-delegating-constructors.md) 16 | - [继承构造函数](./cpp11/11-inherited-constructors.md) 17 | - [nullptr - 指针字面量](./cpp11/12-nullptr.md) 18 | - [long long - 64位整数类型](./cpp11/13-long-long.md) 19 | - [using - 类型别名和别名模板](./cpp11/14-type-alias.md) 20 | 21 | # C++14核心语言特性 22 | 23 | # 其他 24 | 25 | - [更新日志](changelog.md) 26 | - [常见问题](fqa.md) 27 | -------------------------------------------------------------------------------- /book/en/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | - [README](./README.md) 4 | 5 | # Getting Started 6 | 7 | - [Preface](./base/chapter_0.md) 8 | - [Usage Guide](./base/chapter_1.md) 9 | 10 | # C++11 Core Language Features 11 | 12 | - [Type Deduction - auto and decltype](./cpp11/00-auto-and-decltype.md) 13 | - [Defaulted and Deleted Functions](./cpp11/01-default-and-delete.md) 14 | - [List Initialization](./cpp11/09-list-initialization.md) 15 | - [Delegating Constructors](./cpp11/10-delegating-constructors.md) 16 | - [Inherited Constructors](./cpp11/11-inherited-constructors.md) 17 | - [nullptr - Pointer Literal](./cpp11/12-nullptr.md) 18 | - [long long - 64-bit Integer Type](./cpp11/13-long-long.md) 19 | - [using - Type Alias and Alias Template](./cpp11/14-type-alias.md) 20 | 21 | # C++14 Core Language Features 22 | 23 | # Additional Resources 24 | 25 | - [Changelog](changelog.md) 26 | - [Frequently Asked Questions](fqa.md) 27 | -------------------------------------------------------------------------------- /dslings/cpp11/01-default-and-delete-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 01 - default and delete | 禁止函数重载 6 | // 7 | // Tips/提示: 修复编译器错误, 删除错误的函数调用 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker default-and-delete-2 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | void func(int x) { 23 | std::cout << "x = " << x << std::endl; 24 | } 25 | 26 | // 显式删除float参数的重载 27 | void func(float) = delete; 28 | 29 | int main() { 30 | 31 | func(1); // int 32 | func(1.1f); // float 33 | 34 | D2X_WAIT 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /videos/d2x/animations.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class DHighlight(Succession): 4 | def __init__(self, mobject, color=YELLOW, scale_factor=1.1, **kwargs): 5 | start_mobject = mobject.copy() 6 | target_mobject = mobject.copy().scale(scale_factor).set_color(color) 7 | super().__init__( 8 | Transform(mobject, target_mobject), 9 | Transform(mobject, start_mobject), 10 | run_time=1, # default run_time 11 | **kwargs 12 | ) 13 | 14 | class DCameraMove(Succession): 15 | def __init__(self, camera, target_mobject, scale_factor=0.5, **kwargs): 16 | super().__init__( 17 | ApplyMethod(camera.frame.scale, 1 / scale_factor), 18 | ApplyMethod(camera.frame.move_to, target_mobject), 19 | ApplyMethod(camera.frame.scale, scale_factor), 20 | run_time=1, # total run_time 21 | **kwargs 22 | ) -------------------------------------------------------------------------------- /dslings/en/cpp11/01-default-and-delete-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-2.cpp 4 | // 5 | // Exercise: cpp11 | 01 - default and delete | Disabling function overloading 6 | // 7 | // Tips: Fix compiler errors, delete incorrect function calls 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker default-and-delete-2 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | void func(int x) { 23 | std::cout << "x = " << x << std::endl; 24 | } 25 | 26 | // Explicitly delete float parameter overload 27 | void func(float) = delete; 28 | 29 | int main() { 30 | 31 | func(1); // int 32 | func(1.1f); // float 33 | 34 | D2X_WAIT 35 | 36 | return 0; 37 | } -------------------------------------------------------------------------------- /dslings/cpp11/08-literal-type-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/08-literal-type-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 08 - literal type | 自定义字面值类型 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解如何定义字面值类型 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/named_req/LiteralType.html 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker literal-type-1 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Vector { 22 | int x, y; 23 | Vector(int x_, int y_) : x(x_), y(y_) { } 24 | }; 25 | 26 | constexpr Vector add(const Vector& v1, const Vector& v2) { 27 | return Vector(v1.x + v2.x, v1.y + v2.y); 28 | } 29 | 30 | int main() { 31 | 32 | constexpr Vector v1{1, 2}, v2{2, 3}; 33 | constexpr Vector v3 = add(v1, v2); 34 | 35 | std::cout << "[ " << v3.x << ", " << v3.y << " ]" << std::endl; 36 | 37 | D2X_WAIT 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /dslings/cpp11/07-constexpr-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/07-constexpr-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 07 - constexpr | 编译期计算基础: constexpr 和 const的区别 6 | // 7 | // Tips/提示: 修复编译器报错, 并了解编译器变量和编译期函数计算 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/constexpr 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker constexpr 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | int sum_for_1_to(int n) { 22 | return n == 1 ? 1 : n + sum_for_1_to(n - 1); 23 | } 24 | 25 | int main() { 26 | 27 | { // 1. 运行时变量、常量和编译期变量 28 | int size1 = 10; 29 | const int size2 = size1 + 10; 30 | constexpr int size3 = 10 * 3; 31 | 32 | int arr1[size1]; // 选择正确的sizex作为数组大小 33 | } 34 | 35 | { // 2. 编译期计算基础 36 | constexpr int s = sum_for_1_to(4); 37 | d2x_assert_eq(s, 1 + 2 + 3 + 4); 38 | } 39 | 40 | D2X_WAIT 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /dslings/cpp11/01-default-and-delete-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 01 - default and delete | 显示指定构造函数生成行为 6 | // 7 | // Tips/提示: 根据编译器提示使用`= default`和`= delete`修复错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker default-and-delete 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | // default和delete显式控制 -> 编译器默认构造函数的生成行为 23 | struct A { }; 24 | struct B { 25 | B(int x) { std::cout << "B(int x)" << std::endl; } 26 | }; 27 | struct C { 28 | C() { } 29 | C(int x = 1) { std::cout << "C(int x = 1)" << std::endl; } 30 | }; 31 | 32 | int main() { // 不要直接修改main函数中的代码 33 | 34 | A a; 35 | B b; 36 | C c(1); 37 | 38 | D2X_WAIT 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /dslings/cpp11/14-type-alias-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/14-type-alias-3.cpp 4 | // 5 | // Exercise/练习: cpp11 | 14 - type alias | 标准库中的别名模板应用 6 | // 7 | // Tips/提示: 使用别名模板实现标准库风格的_t/_v模板 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | #include 22 | 23 | int main() { 24 | 25 | template 26 | D2X_YOUR_ANSWER my_add_pointer_t = typename std::add_pointer; 27 | 28 | int c = 20; 29 | my_add_pointer_t ptr = &c; 30 | 31 | bool ok = std::is_same, int*>::value; 32 | 33 | d2x_assert(ok); 34 | d2x_assert_eq(*ptr, 20); 35 | 36 | D2X_WAIT 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /dslings/en/cpp11/08-literal-type-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/08-literal-type-1.cpp 4 | // 5 | // Exercise: cpp11 | 08 - literal type | Custom literal types 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand how to define literal types 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/named_req/LiteralType.html 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker literal-type-1 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Vector { 22 | int x, y; 23 | Vector(int x_, int y_) : x(x_), y(y_) { } 24 | }; 25 | 26 | constexpr Vector add(const Vector& v1, const Vector& v2) { 27 | return Vector(v1.x + v2.x, v1.y + v2.y); 28 | } 29 | 30 | int main() { 31 | 32 | constexpr Vector v1{1, 2}, v2{2, 3}; 33 | constexpr Vector v3 = add(v1, v2); 34 | 35 | std::cout << "[ " << v3.x << ", " << v3.y << " ]" << std::endl; 36 | 37 | D2X_WAIT 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /config.xlings: -------------------------------------------------------------------------------- 1 | -- https://xlings.d2learn.org 2 | 3 | xname = "mcpp-standard" -- project name 4 | 5 | -- xim-deps 6 | xim = { 7 | vscode = "", -- config by checker.editor 8 | cpp = "", -- language:[windows:mingw], [linux:gcc], [macos:clang] 9 | mdbook = "0.4.43", -- for d2x book 10 | xppcmds = { 11 | "xmake project -k compile_commands --project=dslings" 12 | } 13 | } 14 | 15 | d2x = { 16 | checker = { 17 | name = "dslings", 18 | editor = "vscode", -- option: vscode, nvim, zed 19 | }, 20 | 21 | commands = { 22 | update = { 23 | linux = "tools/update_upstream.sh", 24 | macosx = "tools/update_upstream.sh", 25 | windows = [[tools\update_upstream.bat]], 26 | }, 27 | }, 28 | 29 | private = { 30 | -- project private attributes 31 | mcpp = { 32 | lang = "en", -- option: en, zh 33 | } 34 | }, 35 | } 36 | 37 | xim[d2x.checker.editor or "vscode"] = "" -- config deps(default version 38 | --xlings_llm_config = "llm.config.xlings" 39 | -------------------------------------------------------------------------------- /dslings/cpp11/09-list-initialization-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 09 - list initialization | 默认初始化语法陷阱 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解默认初始化语法陷阱 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker list-initialization 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | struct Object { 23 | Object() { 24 | x = 0; 25 | std::cout << "Object()" << std::endl; 26 | } 27 | Object(int x) : x(x) { 28 | std::cout << "Object(int): " << x << std::endl; 29 | } 30 | int x; 31 | }; 32 | 33 | int main() { 34 | 35 | Object obj1(); 36 | Object obj2(2); 37 | 38 | d2x_assert_eq(obj1.x, 0); 39 | d2x_assert_eq(obj2.x, 2); 40 | 41 | D2X_WAIT 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /dslings/cpp11/06-scoped-enums-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/06-scoped-enums-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 06 - scoped enums | 传统枚举类型潜在问题 6 | // 7 | // Tips/提示: 通过编译器的错误提示修复代码, 并理解传统枚举类型的潜在问题 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/enum 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker scoped-enums 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | enum Color { 22 | RED, 23 | GREEN, 24 | BLUE, 25 | ORANGE // 1.类型冲突 - 橙色 26 | }; 27 | 28 | enum Fruit { 29 | Apple, 30 | Banana, 31 | ORANGE // 1.类型冲突 - 橙子 32 | }; 33 | 34 | int main() { 35 | 36 | Color color = RED; 37 | Fruit fruit = Apple; 38 | 39 | d2x_assert_eq(color, RED); 40 | d2x_assert_eq(fruit, Apple); 41 | 42 | // 2.符合语法, 但逻辑错误的类型匹配 43 | if (color == Apple) { // 不要删除这行代码 44 | // 代码会运行到这里 45 | D2X_WAIT 46 | } 47 | 48 | if (fruit == RED) { 49 | D2X_WAIT 50 | } 51 | 52 | D2X_WAIT 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /dslings/d2x/honly_logger.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LOGGER_HPP__HONLY 2 | #define LOGGER_HPP__HONLY 3 | 4 | #include 5 | 6 | #ifndef HONLY_LOGGER_TAG 7 | #define HONLY_LOGGER_TAG "HONLY" 8 | #endif 9 | 10 | #define LOG_ENABLE true 11 | #define _HONLY_LOG(fd, ...) if (LOG_ENABLE) { fprintf (fd, __VA_ARGS__); fprintf (fd, "\033[0m\n"); fflush(stdout); } 12 | #define HONLY_LOGI_P(...) { fprintf (stdout, "\033[32m[%s LOGI]: - ", HONLY_LOGGER_TAG); _HONLY_LOG(stdout, __VA_ARGS__); } 13 | #define HONLY_LOGI(...) { fprintf (stdout, "\033[32m[%s LOGI]: %s: %s:%d - ", HONLY_LOGGER_TAG, __func__, __FILE__, __LINE__); _HONLY_LOG(stdout, __VA_ARGS__); } 14 | #define HONLY_LOGD(...) { fprintf (stdout, "\033[37m[%s LOGD]: %s: %s:%d - ", HONLY_LOGGER_TAG, __func__, __FILE__, __LINE__); _HONLY_LOG(stdout, __VA_ARGS__); } 15 | #define HONLY_LOGW(...) { fprintf (stdout, "\033[33m[%s LOGW]: %s: %s:%d - ", HONLY_LOGGER_TAG, __func__, __FILE__, __LINE__); _HONLY_LOG(stdout, __VA_ARGS__); } 16 | #define HONLY_LOGE(...) { fprintf (stdout, "\033[31m[%s LOGE]: %s: %s:%d - ❌ | ", HONLY_LOGGER_TAG, __func__, __FILE__, __LINE__); _HONLY_LOG(stdout, __VA_ARGS__); } 17 | 18 | #endif -------------------------------------------------------------------------------- /dslings/en/cpp11/14-type-alias-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/14-type-alias-3.cpp 4 | // 5 | // Exercise: cpp11 | 14 - type alias | Standard Library Style Alias Templates 6 | // 7 | // Tips: Use alias templates to implement standard library style _t/_v templates 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // Discussion Forum: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker Command: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | #include 22 | 23 | int main() { 24 | 25 | template 26 | D2X_YOUR_ANSWER my_add_pointer_t = typename std::add_pointer; 27 | 28 | int c = 20; 29 | my_add_pointer_t ptr = &c; 30 | 31 | bool ok = std::is_same, int*>::value; 32 | 33 | d2x_assert(ok); 34 | d2x_assert_eq(*ptr, 20); 35 | 36 | D2X_WAIT 37 | 38 | return 0; 39 | } -------------------------------------------------------------------------------- /videos/d2x/video.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | def mcpp_video_start(scene, target_title): 4 | 5 | title = Text(target_title) 6 | logo = VGroup( 7 | Tex(r"\textit{\underline{mcpp-standard}}"), 8 | Tex(r"\textit{+}", color=RED) 9 | ).arrange(RIGHT, buff=0.1).scale(0.8) 10 | 11 | scene.play(Write(logo), run_time=0.8) 12 | scene.bring_to_front(logo) 13 | 14 | scene.play( 15 | logo.animate.to_corner(UP + LEFT), 16 | FadeIn(title), 17 | ) 18 | 19 | return title, logo 20 | 21 | def mcpp_video_end(scene, logo, obj_group=VGroup()): 22 | 23 | scene.play( 24 | logo.animate.move_to(ORIGIN), 25 | FadeOut(obj_group), 26 | run_time=0.7 27 | ) 28 | 29 | scene.wait(0.5) 30 | 31 | ending = VGroup( 32 | Text("开源交互式教程", color=RED).scale(0.9), 33 | Tex(r"\textit{\underline{https://github.com/Sunrisepeak/mcpp-standard}}"), 34 | ).arrange(DOWN, buff=0.15).scale(0.8) 35 | 36 | scene.play( 37 | ReplacementTransform(logo[1], ending[0]), 38 | ReplacementTransform(logo[0], ending[1]), 39 | ) 40 | 41 | scene.play(FadeOut(ending), run_time = 3) -------------------------------------------------------------------------------- /dslings/en/cpp11/01-default-and-delete-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-0.cpp 4 | // 5 | // Exercise: cpp11 | 01 - default and delete | Explicitly specifying constructor generation behavior 6 | // 7 | // Tips: Use `= default` and `= delete` to fix errors based on compiler hints 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker default-and-delete 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | // default and delete explicitly control -> compiler default constructor generation behavior 23 | struct A { }; 24 | struct B { 25 | B(int x) { std::cout << "B(int x)" << std::endl; } 26 | }; 27 | struct C { 28 | C() { } 29 | C(int x = 1) { std::cout << "C(int x = 1)" << std::endl; } 30 | }; 31 | 32 | int main() { // Do not directly modify the code in the main function 33 | 34 | A a; 35 | B b; 36 | C c(1); 37 | 38 | D2X_WAIT 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/09-list-initialization-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-1.cpp 4 | // 5 | // Exercise: cpp11 | 09 - list initialization | Default initialization syntax pitfalls 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand default initialization syntax pitfalls 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker list-initialization 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | struct Object { 23 | Object() { 24 | x = 0; 25 | std::cout << "Object()" << std::endl; 26 | } 27 | Object(int x) : x(x) { 28 | std::cout << "Object(int): " << x << std::endl; 29 | } 30 | int x; 31 | }; 32 | 33 | int main() { 34 | 35 | Object obj1(); 36 | Object obj2(2); 37 | 38 | d2x_assert_eq(obj1.x, 0); 39 | d2x_assert_eq(obj2.x, 2); 40 | 41 | D2X_WAIT 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /dslings/cpp11/03-trailing-return-type.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/03-trailing-return-type.cpp 4 | // 5 | // Exercise/练习: cpp11 | 03 - trailing return type 6 | // 7 | // Tips/提示: 替换D2X_YOUR_ANSWER为正确的类型, 通过所有检查 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_declaration 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker trailing-return-type 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | int add0(double a, int b) { 22 | return a + b; 23 | } 24 | 25 | auto add1(double a, int b) -> int { 26 | return a + b; 27 | } 28 | 29 | template 30 | auto add2(const T1 &a, const T2 &b) -> D2X_YOUR_ANSWER { 31 | return a + b; 32 | } 33 | 34 | auto add3 = [](double a, double b) -> D2X_YOUR_ANSWER { 35 | return a + b; 36 | }; 37 | 38 | int main() { 39 | 40 | d2x_assert_eq(add0(1.1, 2), 3); 41 | d2x_assert_eq(add1(1.1, 2), 3); 42 | d2x_assert_eq(add2(1.1, 2), 3.1); 43 | d2x_assert_eq(add2(1, 2.1), 3.1); 44 | d2x_assert_eq(add3(1.1, 2.1), 3); 45 | 46 | D2X_WAIT 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /dslings/cpp11/00-auto-and-decltype-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 00 - auto and decltype | 自动类型推导 6 | // 7 | // Tips/提示: 使用 auto 和 decltype 修复代码中的错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // 练习交流讨论: http://forum.d2learn.org/post/357 15 | // 16 | // Auto-Checker/自动检测命令: 17 | // 18 | // d2x checker auto-and-decltype 19 | // 20 | 21 | #include 22 | 23 | int main() { 24 | 25 | // 0. 声明定义 26 | int a = 1; 27 | auto a1 = a; // a1 的类型是 int 28 | int b = 2; 29 | D2X_YOUR_ANSWER b1 = b; 30 | 31 | decltype(b) b2 = b; // b2 的类型是 int 32 | D2X_YOUR_ANSWER a2 = a; 33 | 34 | char c = 'c'; 35 | D2X_YOUR_ANSWER c1 = c; 36 | D2X_YOUR_ANSWER c2 = c; 37 | 38 | d2x_assert_eq(a, a1); 39 | d2x_assert_eq(a1, a2); 40 | d2x_assert_eq(b, b1); 41 | d2x_assert_eq(b1, b2); 42 | 43 | D2X_WAIT 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /dslings/d2x/common.lua: -------------------------------------------------------------------------------- 1 | function get_local_lang() 2 | --local config = platform.get_config_info() 3 | local local_lang = "en" -- Default language 4 | -- TODO: config language by xlings.json 5 | if is_host("linux") then 6 | local tmp_local_lang = os.getenv("LANG") or "en" 7 | if tmp_local_lang:find("zh") then 8 | local_lang = "zh" 9 | end 10 | elseif is_host("windows") then 11 | local tmp_local_lang = nil 12 | if find_tool("wmic") then -- Windows 10 and earlier 13 | -- wmic is deprecated in Windows 11, but still available 14 | tmp_local_lang = os.iorun([[wmic os get locale]]) 15 | else -- win11+ 16 | tmp_local_lang = os.iorun([[powershell -NoProfile -ExecutionPolicy Bypass -Command "'{0:X4}' -f (Get-Culture).LCID"]]) 17 | end 18 | if tmp_local_lang and tmp_local_lang:find("0804") then 19 | local_lang = "zh" 20 | end 21 | elseif is_host("macosx") then 22 | local tmp_local_lang = os.iorun([[defaults read -g AppleLocale]]) 23 | if tmp_local_lang and tmp_local_lang:find("zh") then 24 | local_lang = "zh" 25 | end 26 | end 27 | 28 | return local_lang 29 | end 30 | -------------------------------------------------------------------------------- /dslings/en/cpp11/07-constexpr-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/07-constexpr-0.cpp 4 | // 5 | // Exercise: cpp11 | 07 - constexpr | Compile-time computation basics: Difference between constexpr and const 6 | // 7 | // Tips: Fix compiler errors and understand compile-time variables and compile-time function computation 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/constexpr 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker constexpr 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | int sum_for_1_to(int n) { 22 | return n == 1 ? 1 : n + sum_for_1_to(n - 1); 23 | } 24 | 25 | int main() { 26 | 27 | { // 1. Runtime variables, constants, and compile-time variables 28 | int size1 = 10; 29 | const int size2 = size1 + 10; 30 | constexpr int size3 = 10 * 3; 31 | 32 | int arr1[size1]; // Choose the correct sizex as array size 33 | } 34 | 35 | { // 2. Compile-time computation basics 36 | constexpr int s = sum_for_1_to(4); 37 | d2x_assert_eq(s, 1 + 2 + 3 + 4); 38 | } 39 | 40 | D2X_WAIT 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/03-trailing-return-type.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/03-trailing-return-type.cpp 4 | // 5 | // Exercise: cpp11 | 03 - trailing return type 6 | // 7 | // Tips: Replace D2X_YOUR_ANSWER with the correct type to pass all checks 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_declaration 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker trailing-return-type 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | int add0(double a, int b) { 22 | return a + b; 23 | } 24 | 25 | auto add1(double a, int b) -> int { 26 | return a + b; 27 | } 28 | 29 | template 30 | auto add2(const T1 &a, const T2 &b) -> D2X_YOUR_ANSWER { 31 | return a + b; 32 | } 33 | 34 | auto add3 = [](double a, double b) -> D2X_YOUR_ANSWER { 35 | return a + b; 36 | }; 37 | 38 | int main() { 39 | 40 | d2x_assert_eq(add0(1.1, 2), 3); 41 | d2x_assert_eq(add1(1.1, 2), 3); 42 | d2x_assert_eq(add2(1.1, 2), 3.1); 43 | d2x_assert_eq(add2(1, 2.1), 3.1); 44 | d2x_assert_eq(add3(1.1, 2.1), 3); 45 | 46 | D2X_WAIT 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /dslings/cpp11/00-auto-and-decltype-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-3.cpp 4 | // 5 | // Exercise/练习: cpp11 | 00 - auto and decltype | 函数返回值类型推导 6 | // 7 | // Tips/提示: 使用 auto 和 decltype 修复代码中的错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // 练习交流讨论: http://forum.d2learn.org/post/357 15 | // 16 | // Auto-Checker/自动检测命令: 17 | // 18 | // d2x checker auto-and-decltype-3 19 | // 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | // 3. 函数返回值类型 27 | 28 | auto add_func(int a, double b) -> decltype(a + b) { 29 | return a + b; 30 | } 31 | 32 | template 33 | D2X_YOUR_ANSWER minus_func(T1 a, T2 b) -> D2X_YOUR_ANSWER { 34 | return a - b; 35 | } 36 | 37 | int main() { 38 | 39 | d2x_assert_eq(minus_func(1, 2), -1); 40 | d2x_assert_eq(minus_func(2, 1), 1); 41 | d2x_assert_eq(minus_func(1, 2.1), -1.1); 42 | 43 | D2X_WAIT 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /dslings/cpp11/14-type-alias-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/14-type-alias-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 14 - type alias | 基本类型别名 6 | // 7 | // Tips/提示: 使用using关键字定义类型别名,替换传统的typedef 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. 基本类型别名定义 27 | D2X_YOUR_ANSWER Integer = int; 28 | D2X_YOUR_ANSWER = int; 29 | 30 | bool ok = std::is_same::value; d2x_assert(ok); 31 | ok = std::is_same::value; d2x_assert(ok); 32 | 33 | // 2. 使用类型别名 34 | Integer a = 42; 35 | Real b = 3.14; 36 | 37 | // 3. 验证类型别名 38 | d2x_assert_eq(a, 42); 39 | d2x_assert_eq(b, 3.14); 40 | 41 | // 4. 类型别名本质相同 42 | int c = 100; 43 | Integer d = c; // 可以赋值,因为本质都是int 44 | 45 | d2x_assert_eq(c, d); 46 | 47 | D2X_WAIT 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /dslings/d2x/common.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_HPP_D2X 2 | #define COMMON_HPP_D2X 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #define d2x_assert(expr) \ 10 | { \ 11 | if (!(expr)) { \ 12 | HONLY_LOGW("❌(error) | %s", #expr); \ 13 | } else { \ 14 | HONLY_LOGI_P("✅ | %s", #expr); \ 15 | } \ 16 | } 17 | 18 | #define d2x_assert_eq(a, b) \ 19 | { \ 20 | if (a != b) {\ 21 | HONLY_LOGW("❌ | %s == %s (%s == %s)", \ 22 | #a, #b, std::to_string(a).c_str(), std::to_string(b).c_str()); \ 23 | } else {\ 24 | HONLY_LOGI_P("✅ | %s == %s (%s == %s)", \ 25 | #a, #b, std::to_string(a).c_str(), std::to_string(b).c_str()); \ 26 | } \ 27 | } 28 | 29 | #define D2X_WAIT HONLY_LOGW("🥳 Delete the D2X_WAIT to continue..."); 30 | #define D2X_YOUR_ANSWER 31 | #define D2X_DONT_DELETE_THIS(x) x 32 | 33 | template 34 | class d2x_is_invocable { 35 | private: 36 | template 37 | static auto test(U* f) -> decltype((*f)(std::declval()...), std::true_type()); 38 | 39 | template 40 | static std::false_type test(...); 41 | 42 | public: 43 | static constexpr bool value = decltype(test(nullptr))::value; 44 | }; 45 | 46 | #endif -------------------------------------------------------------------------------- /dslings/cpp11/00-auto-and-decltype-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 00 - auto and decltype | 表达式类型推导 6 | // 7 | // Tips/提示: 使用 auto 和 decltype 修复代码中的错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // 练习交流讨论: http://forum.d2learn.org/post/357 15 | // 16 | // Auto-Checker/自动检测命令: 17 | // 18 | // d2x checker auto-and-decltype-1 19 | // 20 | 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. 表达式 27 | int a = 1; 28 | auto a1 = a + 2; 29 | D2X_YOUR_ANSWER a2 = a + 2 + 1.1; 30 | 31 | int b = 2; 32 | D2X_YOUR_ANSWER b1 = a + 0.1; 33 | decltype(a + b + 1.1) b2 = a + b + 1.1; 34 | 35 | char c = 'c'; 36 | D2X_YOUR_ANSWER c1 = 1 + c; 37 | D2X_YOUR_ANSWER c2 = 2 + 'a'; 38 | 39 | d2x_assert_eq(a2, a + 2 + 1.1); 40 | d2x_assert_eq(b1, a + 0.1); 41 | d2x_assert_eq(c1, 1 + c); 42 | d2x_assert_eq(c2, 2 + 'a'); 43 | 44 | D2X_WAIT 45 | 46 | return 0; 47 | } -------------------------------------------------------------------------------- /dslings/cpp11/02-final-and-override-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 02 - final and override 6 | // 7 | // Tips/提示: 修正代码中final的使用错误问题 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker final-and-override-1 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct A { 24 | virtual int func1() { 25 | return 1; 26 | } 27 | int func2() { return 2; } 28 | }; 29 | 30 | struct B : A { 31 | 32 | int func1() { 33 | return 3; 34 | } 35 | 36 | int func2() { 37 | return 4; 38 | } 39 | }; 40 | 41 | struct C : B { 42 | 43 | }; 44 | 45 | int main() { 46 | 47 | B final; // 不要直接修改main函数中的代码 48 | d2x_assert_eq(final.func1(), 3); // B::func1() 49 | d2x_assert_eq(final.func2(), 4); // B::func2() 50 | 51 | A *a = &final; 52 | d2x_assert_eq(a->func1(), 3); // B::func1() 53 | d2x_assert_eq(a->func2(), 2); // A::func2() 54 | 55 | D2X_WAIT 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /book/src/base/chapter_0.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./chapter_0.html 7 | [English]: ../en/base/chapter_0.html 8 | 9 | # 序言 10 | 11 | mcpp-standard是一个开源、强调代码实践的`现代C++核心语言特性`教程项目。项目的总体结构为[Book + Video + Code + X]。为使用者提供了 在线电子书、对应的讲解视频、配套练习代码, 同时也提供了用于讨论交流的论坛和定期的学习活动... 12 | 13 | - [Book: 在线电子书](https://sunrisepeak.github.io/mcpp-standard) 14 | - [Video: 讲解视频](https://space.bilibili.com/65858958/lists/5208246?type=season) 15 | - [Code: 练习代码](https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings) 16 | - [X: mcpp论坛](https://forum.d2learn.org/category/20) 17 | 18 | ## 语言支持 19 | 20 | | 中文 | English | 仓库 | 21 | | --- | --- | --- | 22 | | [中文](./) | [English](../en/base/chapter_0.html) | [Github](https://github.com/Sunrisepeak/mcpp-standard) | 23 | 24 | ## 活动 | [ 📣 MSCP - mcpp项目学习与贡献者培养计划 ](https://moga.d2learn.org/activity/mscp/intro.html) 25 | 26 | > MSCP是一款基于mcpp-standard开源项目开发的"地球Online"风格的角色扮演游戏。在游戏中你将扮演一个"编程初学者", 为了入门"现代C++"并揭露其背后的真相, 踏上了一条充满挑战和惊奇的现代C++学习之路... 27 | 28 | - `价格:` 免费 29 | - `开发者:` [Sunrisepeak](https://github.com/Sunrisepeak) 30 | - `发行商:` [MOGA](https://moga.d2learn.org) 31 | - `发行时间:` 2025年10月 32 | - `游戏体量:` 100H - 200H之间 33 | - `标签:` 类魂系列、模拟人生、🌍Online、程序员、C++、开源、费曼学习法 34 | - [-> 游戏详情](https://moga.d2learn.org/activity/mscp/intro.html) 35 | -------------------------------------------------------------------------------- /dslings/en/cpp11/00-auto-and-decltype-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-0.cpp 4 | // 5 | // Exercise: cpp11 | 00 - auto and decltype | Automatic Type Deduction 6 | // 7 | // Tips: Use auto and decltype to fix errors in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // Forum: https://forum.d2learn.org/category/20 15 | // 16 | // Auto-Checker command: 17 | // 18 | // d2x checker auto-and-decltype 19 | // 20 | 21 | #include 22 | 23 | int main() { 24 | 25 | // 0. Declaration and definition 26 | int a = 1; 27 | auto a1 = a; // a1's type is int 28 | int b = 2; 29 | D2X_YOUR_ANSWER b1 = b; 30 | 31 | decltype(b) b2 = b; // b2's type is int 32 | D2X_YOUR_ANSWER a2 = a; 33 | 34 | char c = 'c'; 35 | D2X_YOUR_ANSWER c1 = c; 36 | D2X_YOUR_ANSWER c2 = c; 37 | 38 | d2x_assert_eq(a, a1); 39 | d2x_assert_eq(a1, a2); 40 | d2x_assert_eq(b, b1); 41 | d2x_assert_eq(b1, b2); 42 | 43 | D2X_WAIT 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /dslings/en/cpp11/00-auto-and-decltype-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-3.cpp 4 | // 5 | // Exercise: cpp11 | 00 - auto and decltype | Function Return Type Deduction 6 | // 7 | // Tips: Use auto and decltype to fix errors in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // Forum: https://forum.d2learn.org/category/20 15 | // 16 | // Auto-Checker command: 17 | // 18 | // d2x checker auto-and-decltype-3 19 | // 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | // 3. Function return types 27 | 28 | auto add_func(int a, double b) -> decltype(a + b) { 29 | return a + b; 30 | } 31 | 32 | template 33 | D2X_YOUR_ANSWER minus_func(T1 a, T2 b) -> D2X_YOUR_ANSWER { 34 | return a - b; 35 | } 36 | 37 | int main() { 38 | 39 | d2x_assert_eq(minus_func(1, 2), -1); 40 | d2x_assert_eq(minus_func(2, 1), 1); 41 | d2x_assert_eq(minus_func(1, 2.1), -1.1); 42 | 43 | D2X_WAIT 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /dslings/cpp11/09-list-initialization-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 09 - list initialization | 窄化检查 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解列表初始化的窄化检查 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker list-initialization 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | int main() { 23 | 24 | int a1 = 1.1; 25 | d2x_assert_eq(a1, 1); 26 | 27 | int a2 = 1.1; 28 | int a3 = { 1.1 }; 29 | d2x_assert_eq(a2, 1); 30 | d2x_assert_eq(a3, 1); 31 | 32 | double b1 { 1.1 }; 33 | constexpr double c1 { 2.2 }; 34 | 35 | int b2 { b1 }; 36 | int c2 { c1 }; 37 | 38 | d2x_assert_eq(b2, 1); 39 | d2x_assert_eq(c2, 2); 40 | 41 | int arr1[] = { 1, 2.2, 3 }; 42 | d2x_assert_eq(arr1[1], 2); 43 | 44 | int arr2[4] { 1, b1, c1 }; 45 | d2x_assert_eq(arr2[1], 1); 46 | d2x_assert_eq(arr2[2], 2); 47 | d2x_assert_eq(arr2[3], 0); 48 | 49 | D2X_WAIT 50 | 51 | return 0; 52 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/00-auto-and-decltype-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-1.cpp 4 | // 5 | // Exercise: cpp11 | 00 - auto and decltype | Expression Type Deduction 6 | // 7 | // Tips: Use auto and decltype to fix errors in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // Forum: https://forum.d2learn.org/category/20 15 | // 16 | // Auto-Checker command: 17 | // 18 | // d2x checker auto-and-decltype-1 19 | // 20 | 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. Expressions 27 | int a = 1; 28 | auto a1 = a + 2; 29 | D2X_YOUR_ANSWER a2 = a + 2 + 1.1; 30 | 31 | int b = 2; 32 | D2X_YOUR_ANSWER b1 = a + 0.1; 33 | decltype(a + b + 1.1) b2 = a + b + 1.1; 34 | 35 | char c = 'c'; 36 | D2X_YOUR_ANSWER c1 = 1 + c; 37 | D2X_YOUR_ANSWER c2 = 2 + 'a'; 38 | 39 | d2x_assert_eq(a2, a + 2 + 1.1); 40 | d2x_assert_eq(b1, a + 0.1); 41 | d2x_assert_eq(c1, 1 + c); 42 | d2x_assert_eq(c2, 2 + 'a'); 43 | 44 | D2X_WAIT 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /dslings/en/cpp11/06-scoped-enums-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/06-scoped-enums-0.cpp 4 | // 5 | // Exercise: cpp11 | 06 - scoped enums | Traditional enum type potential issues 6 | // 7 | // Tips: Fix code through compiler error prompts and understand potential issues with traditional enum types 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/enum 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker scoped-enums 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | enum Color { 22 | RED, 23 | GREEN, 24 | BLUE, 25 | ORANGE // 1. Type conflict - Orange color 26 | }; 27 | 28 | enum Fruit { 29 | Apple, 30 | Banana, 31 | ORANGE // 1. Type conflict - Orange fruit 32 | }; 33 | 34 | int main() { 35 | 36 | Color color = RED; 37 | Fruit fruit = Apple; 38 | 39 | d2x_assert_eq(color, RED); 40 | d2x_assert_eq(fruit, Apple); 41 | 42 | // 2. Syntactically correct, but logically wrong type matching 43 | if (color == Apple) { // Do not delete this line of code 44 | // Code will run here 45 | D2X_WAIT 46 | } 47 | 48 | if (fruit == RED) { 49 | D2X_WAIT 50 | } 51 | 52 | D2X_WAIT 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /dslings/cpp11/02-final-and-override-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 02 - final and override 6 | // 7 | // Tips/提示: 修正代码中override的使用错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker final-and-override 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct A { 24 | virtual void func1() { 25 | std::cout << "A::func1()" << std::endl; 26 | } 27 | 28 | void func2() { 29 | std::cout << "A::func2()" << std::endl; 30 | } 31 | }; 32 | 33 | struct B : A { 34 | void func1() { 35 | std::cout << "B::func1()" << std::endl; 36 | } 37 | 38 | void func2() override { 39 | std::cout << "B::func2()" << std::endl; 40 | } 41 | }; 42 | 43 | 44 | int main() { 45 | 46 | B override; // 不要直接修改main函数中的代码 47 | override.func1(); // B::func1() 48 | override.func2(); // B::func2() 49 | 50 | A *a = &override; 51 | a->func1(); // B::func1() 52 | a->func2(); // A::func2() 53 | 54 | D2X_WAIT 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/02-final-and-override-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-1.cpp 4 | // 5 | // Exercise: cpp11 | 02 - final and override 6 | // 7 | // Tips: Correct the usage errors of final in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker final-and-override-1 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct A { 24 | virtual int func1() { 25 | return 1; 26 | } 27 | int func2() { return 2; } 28 | }; 29 | 30 | struct B : A { 31 | 32 | int func1() { 33 | return 3; 34 | } 35 | 36 | int func2() { 37 | return 4; 38 | } 39 | }; 40 | 41 | struct C : B { 42 | 43 | }; 44 | 45 | int main() { 46 | 47 | B final; // Do not directly modify the code in the main function 48 | d2x_assert_eq(final.func1(), 3); // B::func1() 49 | d2x_assert_eq(final.func2(), 4); // B::func2() 50 | 51 | A *a = &final; 52 | d2x_assert_eq(a->func1(), 3); // B::func1() 53 | d2x_assert_eq(a->func2(), 2); // A::func2() 54 | 55 | D2X_WAIT 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /dslings/cpp11/12-nullptr-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/12-nullptr-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 12 - nullptr | 指针字面量 - 模板编程 6 | // 7 | // Tips/提示: 使用 nullptr 在模板编程中提供更好的类型安全性 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/12-nullptr.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | #include 22 | 23 | // 模板函数示例 24 | template 25 | void processPointer(T* ptr) { } 26 | 27 | // 模板函数,返回传入值的副本 28 | template 29 | T clone(const T& t) { 30 | return t; 31 | } 32 | 33 | int main() { 34 | 35 | // 1. nullptr 在模板中的类型推导 36 | auto ptr1 = nullptr; // ptr1 的类型是 std::nullptr_t 37 | static_assert(std::is_same::value, "类型推导错误"); 38 | 39 | // 2. nullptr 在模板函数中的优势 - 类型推导安全 40 | // 观察编译器报错, 尝试显式指定模板参数解决报错 41 | processPointer(clone(0)); 42 | processPointer(clone(NULL)); 43 | 44 | processPointer(clone(nullptr)); 45 | processPointer(clone(nullptr)); 46 | 47 | D2X_WAIT 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /dslings/cpp11/13-long-long-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/13-long-long-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 13 - long long | 64位整数类型 - 基础用法 6 | // 7 | // Tips/提示: 使用 long long 类型和对应的字面量后缀 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/types 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/13-long-long.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker long-long 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. 基本声明和初始化 27 | D2X_YOUR_ANSWER val1 = 1; 28 | D2X_YOUR_ANSWER val2 = -1; 29 | 30 | // 2. 整数表示范围 31 | unsigned int uVal1 = 18446744073709551615; 32 | d2x_assert_eq(uVal1, 18446744073709551615ULL); 33 | 34 | // 3. 类型推导和字面量 35 | // 修复下面的声明,让 auto 正确推导类型 36 | auto longlong = 1234567890; 37 | auto ulonglong = 9876543210; 38 | 39 | bool is_longlong = std::is_same::value; 40 | bool is_ulonglong = std::is_same::value; 41 | 42 | d2x_assert(is_longlong == true); 43 | d2x_assert(is_ulonglong == true); 44 | 45 | D2X_WAIT 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /dslings/cpp11/13-long-long-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/13-long-long-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 13 - long long | 64位整数类型 - 大数应用和边界值 6 | // 7 | // Tips/提示: 使用 long long 处理大整数和边界值计算 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/types 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/13-long-long.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker long-long 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. 获取整数类型的边界值 27 | auto maxInt = std::numeric_limits::max(); 28 | auto maxLL = std::numeric_limits::max(); 29 | auto minLL = std::numeric_limits::min(); 30 | auto maxULL = std::numeric_limits::max(); 31 | 32 | d2x_assert_eq(maxInt, 2147483647); 33 | d2x_assert_eq(maxLL, 9223372036854775807LL); 34 | d2x_assert_eq(minLL, -9223372036854775807LL - 1); 35 | d2x_assert_eq(maxULL, 18446744073709551615ULL); 36 | 37 | // 2. 大整数应用 - 表示世界人口 38 | int currentPopulation = 7800000000; 39 | d2x_assert_eq(currentPopulation, 7800000000ULL); 40 | 41 | D2X_WAIT 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /dslings/en/cpp11/09-list-initialization-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-0.cpp 4 | // 5 | // Exercise: cpp11 | 09 - list initialization | Narrowing checks 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand narrowing checks in list initialization 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker list-initialization 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | int main() { 23 | 24 | int a1 = 1.1; 25 | d2x_assert_eq(a1, 1); 26 | 27 | int a2 = 1.1; 28 | int a3 = { 1.1 }; 29 | d2x_assert_eq(a2, 1); 30 | d2x_assert_eq(a3, 1); 31 | 32 | double b1 { 1.1 }; 33 | constexpr double c1 { 2.2 }; 34 | 35 | int b2 { b1 }; 36 | int c2 { c1 }; 37 | 38 | d2x_assert_eq(b2, 1); 39 | d2x_assert_eq(c2, 2); 40 | 41 | int arr1[] = { 1, 2.2, 3 }; 42 | d2x_assert_eq(arr1[1], 2); 43 | 44 | int arr2[4] { 1, b1, c1 }; 45 | d2x_assert_eq(arr2[1], 1); 46 | d2x_assert_eq(arr2[2], 2); 47 | d2x_assert_eq(arr2[3], 0); 48 | 49 | D2X_WAIT 50 | 51 | return 0; 52 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/02-final-and-override-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-0.cpp 4 | // 5 | // Exercise: cpp11 | 02 - final and override 6 | // 7 | // Tips: Correct the usage errors of override in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker final-and-override 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct A { 24 | virtual void func1() { 25 | std::cout << "A::func1()" << std::endl; 26 | } 27 | 28 | void func2() { 29 | std::cout << "A::func2()" << std::endl; 30 | } 31 | }; 32 | 33 | struct B : A { 34 | void func1() { 35 | std::cout << "B::func1()" << std::endl; 36 | } 37 | 38 | void func2() override { 39 | std::cout << "B::func2()" << std::endl; 40 | } 41 | }; 42 | 43 | 44 | int main() { 45 | 46 | B override; // Do not directly modify the code in the main function 47 | override.func1(); // B::func1() 48 | override.func2(); // B::func2() 49 | 50 | A *a = &override; 51 | a->func1(); // B::func1() 52 | a->func2(); // A::func2() 53 | 54 | D2X_WAIT 55 | 56 | return 0; 57 | } -------------------------------------------------------------------------------- /tools/update_upstream.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 脚本名称:update_upstream.sh 4 | 5 | set -euo pipefail 6 | 7 | UPSTREAM_URL="https://github.com/Sunrisepeak/mcpp-standard.git" 8 | BRANCH_NAME="main" 9 | 10 | echo "[1] - 检查是否已添加 upstream 远程..." 11 | if ! git remote get-url upstream &> /dev/null; then 12 | echo "添加 upstream: $UPSTREAM_URL" 13 | git remote add upstream "$UPSTREAM_URL" 14 | else 15 | echo "✅ upstream 已存在" 16 | fi 17 | 18 | echo "[2] - 获取 upstream 更新..." 19 | git fetch upstream 20 | 21 | echo "[3] - 切换到 $BRANCH_NAME 分支..." 22 | git checkout $BRANCH_NAME 23 | 24 | 25 | echo "[4] - 检测到本地改动,自动备份中..." 26 | 27 | TIMESTAMP=$(date +"%Y%m%d-%H%M%S") 28 | BACKUP_BRANCH="solutions-$TIMESTAMP" 29 | 30 | echo "🔀 创建备份分支: $BACKUP_BRANCH" 31 | git checkout -b "$BACKUP_BRANCH" 32 | 33 | # 判断是否有工作区改动 34 | HAS_UNSTAGED_CHANGES=false 35 | if ! git diff --quiet || ! git diff --cached --quiet; then 36 | HAS_UNSTAGED_CHANGES=true 37 | fi 38 | 39 | if $HAS_UNSTAGED_CHANGES; then 40 | echo "📦 提交工作目录的未提交改动" 41 | git add . 42 | git commit -m "🧶 自动备份:本地改动 - $TIMESTAMP" 43 | fi 44 | 45 | echo "✅ 本地改动已保存到 $BACKUP_BRANCH 分支" 46 | 47 | # 回到 main 分支准备 rebase 48 | git checkout $BRANCH_NAME 49 | 50 | echo "[5] - 使用 rebase 同步 upstream/$BRANCH_NAME 到本地 $BRANCH_NAME..." 51 | if ! git rebase upstream/$BRANCH_NAME; then 52 | echo "❌ 出现冲突,请手动解决后完成 rebase" 53 | exit 1 54 | fi 55 | 56 | echo "✅ 更新完成!" -------------------------------------------------------------------------------- /dslings/cpp11/09-list-initialization-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 09 - list initialization | 容器列表初始化 6 | // 7 | // Tips/提示: 实现一个支持列表初始化的构造函数, 计算容器大小, 了解initializer_list并通过运行时检查 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // - https://en.cppreference.com/w/cpp/utility/initializer_list.html 13 | // 14 | // Auto-Checker/自动检测命令: 15 | // 16 | // d2x checker list-initialization 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | class MyVector { 26 | int mSize; 27 | 28 | public: 29 | D2X_YOUR_ANSWER 30 | 31 | int size() const { 32 | return mSize; 33 | } 34 | }; 35 | 36 | int main() { 37 | 38 | std::vector vec1 = { 1, 2, 3 }; 39 | d2x_assert_eq(vec1.size(), 3); 40 | std::vector vec2 { 1, 2, 3, 4, 5 }; 41 | d2x_assert_eq(vec2.size(), 5); 42 | 43 | MyVector myVec1 = { 1, 2, 3 }; 44 | d2x_assert_eq(myVec1.size(), 3); 45 | MyVector myVec2 { 1, 2, 3, 4, 5 }; 46 | d2x_assert_eq(myVec2.size(), 5); 47 | 48 | D2X_WAIT 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /dslings/cpp11/12-nullptr-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/12-nullptr-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 12 - nullptr | 指针字面量 - 函数重载 6 | // 7 | // Tips/提示: 使用 nullptr 解决函数重载中的歧义问题 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/12-nullptr.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | 22 | bool process_int_called = false; 23 | bool process_ptr_called = false; 24 | bool display_int_called = false; 25 | bool display_ptr_called = false; 26 | 27 | void process(int* ptr) { 28 | process_ptr_called = true; 29 | } 30 | 31 | void process(int value) { 32 | process_int_called = true; 33 | } 34 | 35 | void display(int* ptr) { 36 | display_ptr_called = true; 37 | } 38 | 39 | void display(int value) { 40 | display_int_called = true; 41 | } 42 | 43 | int main() { 44 | 45 | display(0); 46 | process(nullptr); 47 | display(NULL); 48 | process(NULL); 49 | 50 | d2x_assert(process_int_called); 51 | d2x_assert(display_int_called); 52 | d2x_assert(display_ptr_called); 53 | d2x_assert(display_ptr_called); 54 | 55 | D2X_WAIT 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /dslings/cpp11/14-type-alias-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/14-type-alias-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 14 - type alias | 别名模板基础 6 | // 7 | // Tips/提示: 使用别名模板为模板类型创建别名 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | // 1. 基本别名模板 27 | template 28 | D2X_YOUR_ANSWER Vec = std::vector; 29 | 30 | // 2. 固定长度的别名模板 31 | template 32 | using Vec3 = std::array; 33 | 34 | // 3. 带默认参数的别名模板 35 | template 36 | using Heap = std::priority_queue, Compare>; 37 | 38 | int main() { 39 | 40 | Vec numbers = {1, 2, 3}; 41 | Vec3 v3 = {1.0f, 2.0f, 3.0f}; 42 | Heap minHeap; 43 | 44 | d2x_assert_eq(numbers[0], 1); 45 | d2x_assert_eq(numbers[1], 2); 46 | d2x_assert_eq(numbers[2], 3); 47 | 48 | d2x_assert_eq(v3[0], 1.0f); 49 | d2x_assert_eq(v3[1], 2.0f); 50 | d2x_assert_eq(v3[2], 3.0f); 51 | 52 | D2X_WAIT 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /dslings/en/cpp11/14-type-alias-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/14-type-alias-0.cpp 4 | // 5 | // Exercise: cpp11 | 14 - type alias | Basic Type Aliases 6 | // 7 | // Tips: Use the using keyword to define type aliases, replacing traditional typedef 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // Discussion Forum: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker Command: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. Basic type alias definition 27 | D2X_YOUR_ANSWER Integer = int; 28 | D2X_YOUR_ANSWER = int; 29 | 30 | bool ok = std::is_same::value; d2x_assert(ok); 31 | ok = std::is_same::value; d2x_assert(ok); 32 | 33 | // 2. Using type aliases 34 | Integer a = 42; 35 | Real b = 3.14; 36 | 37 | // 3. Verifying type aliases 38 | d2x_assert_eq(a, 42); 39 | d2x_assert_eq(b, 3.14); 40 | 41 | // 4. Type aliases are essentially the same 42 | int c = 100; 43 | Integer d = c; // Can assign because they are essentially both int 44 | 45 | d2x_assert_eq(c, d); 46 | 47 | D2X_WAIT 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /dslings/cpp11/01-default-and-delete-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 01 - default and delete | 不可拷贝对像 6 | // 7 | // Tips/提示: 根据编译器提示使用`= default`和`= delete`修复错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker default-and-delete-1 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | // 实现std::unique_ptr不可以拷贝, 但可以移动的属性 23 | struct UniquePtr { 24 | void *dataPtr; 25 | UniquePtr() = default; 26 | }; 27 | 28 | int main() { // 不要直接修改main函数中的代码 29 | 30 | // std::unique_ptr a(new int(1)); 31 | UniquePtr a; 32 | 33 | // 对像不可拷贝/复制 34 | // std::unique_ptr b = a; // error 35 | d2x_assert(std::is_copy_constructible::value == false); 36 | // a = b; // error 37 | d2x_assert(std::is_copy_assignable::value == false); 38 | 39 | // 对像可移动 40 | // std::unique_ptr c = std::move(a); // ok 41 | d2x_assert(std::is_move_constructible::value == true); 42 | // a = std::move(c); // ok 43 | d2x_assert(std::is_move_assignable::value == true); 44 | 45 | D2X_WAIT 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/12-nullptr-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/12-nullptr-1.cpp 4 | // 5 | // Exercise: cpp11 | 12 - nullptr | Pointer Literal - Function Overloading 6 | // 7 | // Tips: Use nullptr to resolve ambiguity in function overloading 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/en/cpp11/12-nullptr.md 12 | // 13 | // Exercise discussion: http://forum.d2learn.org/post/359 14 | // 15 | // Auto-Checker command: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | 22 | bool process_int_called = false; 23 | bool process_ptr_called = false; 24 | bool display_int_called = false; 25 | bool display_ptr_called = false; 26 | 27 | void process(int* ptr) { 28 | process_ptr_called = true; 29 | } 30 | 31 | void process(int value) { 32 | process_int_called = true; 33 | } 34 | 35 | void display(int* ptr) { 36 | display_ptr_called = true; 37 | } 38 | 39 | void display(int value) { 40 | display_int_called = true; 41 | } 42 | 43 | int main() { 44 | 45 | display(0); 46 | process(nullptr); 47 | display(NULL); 48 | process(NULL); 49 | 50 | d2x_assert(process_int_called); 51 | d2x_assert(display_int_called); 52 | d2x_assert(display_ptr_called); 53 | d2x_assert(display_ptr_called); 54 | 55 | D2X_WAIT 56 | 57 | return 0; 58 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/09-list-initialization-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-2.cpp 4 | // 5 | // Exercise: cpp11 | 09 - list initialization | Container list initialization 6 | // 7 | // Tips: Implement a constructor that supports list initialization, calculate container size, understand initializer_list and pass runtime checks 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // - https://en.cppreference.com/w/cpp/utility/initializer_list.html 13 | // 14 | // Auto-Checker command: 15 | // 16 | // d2x checker list-initialization 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | class MyVector { 26 | int mSize; 27 | 28 | public: 29 | D2X_YOUR_ANSWER 30 | 31 | int size() const { 32 | return mSize; 33 | } 34 | }; 35 | 36 | int main() { 37 | 38 | std::vector vec1 = { 1, 2, 3 }; 39 | d2x_assert_eq(vec1.size(), 3); 40 | std::vector vec2 { 1, 2, 3, 4, 5 }; 41 | d2x_assert_eq(vec2.size(), 5); 42 | 43 | MyVector myVec1 = { 1, 2, 3 }; 44 | d2x_assert_eq(myVec1.size(), 3); 45 | MyVector myVec2 { 1, 2, 3, 4, 5 }; 46 | d2x_assert_eq(myVec2.size(), 5); 47 | 48 | D2X_WAIT 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/13-long-long-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/13-long-long-1.cpp 4 | // 5 | // Exercise: cpp11 | 13 - long long | 64-bit Integer Type - Large Number Applications and Boundary Values 6 | // 7 | // Tips: Use long long to handle large integers and boundary value calculations 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/types 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/en/src/cpp11/13-long-long.md 12 | // 13 | // Exercise discussion: http://forum.d2learn.org 14 | // 15 | // Auto-Checker command: 16 | // 17 | // d2x checker long-long 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. Get boundary values of integer types 27 | auto maxInt = std::numeric_limits::max(); 28 | auto maxLL = std::numeric_limits::max(); 29 | auto minLL = std::numeric_limits::min(); 30 | auto maxULL = std::numeric_limits::max(); 31 | 32 | d2x_assert_eq(maxInt, 2147483647); 33 | d2x_assert_eq(maxLL, 9223372036854775807LL); 34 | d2x_assert_eq(minLL, -9223372036854775807LL - 1); 35 | d2x_assert_eq(maxULL, 18446744073709551615ULL); 36 | 37 | // 2. Large integer application - representing world population 38 | int currentPopulation = 7800000000; 39 | d2x_assert_eq(currentPopulation, 7800000000ULL); 40 | 41 | D2X_WAIT 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/13-long-long-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/13-long-long-0.cpp 4 | // 5 | // Exercise: cpp11 | 13 - long long | 64-bit Integer Type - Basic Usage 6 | // 7 | // Tips: Use long long type and corresponding literal suffixes 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/types 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/en/src/cpp11/13-long-long.md 12 | // 13 | // Exercise discussion: http://forum.d2learn.org 14 | // 15 | // Auto-Checker command: 16 | // 17 | // d2x checker long-long 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. Basic declaration and initialization 27 | D2X_YOUR_ANSWER val1 = 1; 28 | D2X_YOUR_ANSWER val2 = -1; 29 | 30 | // 2. Integer representation range 31 | unsigned int uVal1 = 18446744073709551615; 32 | d2x_assert_eq(uVal1, 18446744073709551615ULL); 33 | 34 | // 3. Type deduction and literals 35 | // Fix the declarations below to let auto correctly deduce the types 36 | auto longlong = 1234567890; 37 | auto ulonglong = 9876543210; 38 | 39 | bool is_longlong = std::is_same::value; 40 | bool is_ulonglong = std::is_same::value; 41 | 42 | d2x_assert(is_longlong == true); 43 | d2x_assert(is_ulonglong == true); 44 | 45 | D2X_WAIT 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /dslings/en/cpp11/14-type-alias-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/14-type-alias-2.cpp 4 | // 5 | // Exercise: cpp11 | 14 - type alias | Alias Templates Basics 6 | // 7 | // Tips: Use alias templates to create aliases for template types 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // Discussion Forum: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker Command: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | // 1. Basic alias template 27 | template 28 | D2X_YOUR_ANSWER Vec = std::vector; 29 | 30 | // 2. Fixed-length alias template 31 | template 32 | using Vec3 = std::array; 33 | 34 | // 3. Alias template with default parameters 35 | template 36 | using Heap = std::priority_queue, Compare>; 37 | 38 | int main() { 39 | 40 | Vec numbers = {1, 2, 3}; 41 | Vec3 v3 = {1.0f, 2.0f, 3.0f}; 42 | Heap minHeap; 43 | 44 | d2x_assert_eq(numbers[0], 1); 45 | d2x_assert_eq(numbers[1], 2); 46 | d2x_assert_eq(numbers[2], 3); 47 | 48 | d2x_assert_eq(v3[0], 1.0f); 49 | d2x_assert_eq(v3[1], 2.0f); 50 | d2x_assert_eq(v3[2], 3.0f); 51 | 52 | D2X_WAIT 53 | 54 | return 0; 55 | } -------------------------------------------------------------------------------- /dslings/cpp11/14-type-alias-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/14-type-alias-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 14 - type alias | 复杂类型和函数指针别名 6 | // 7 | // Tips/提示: 使用using关键字为复杂类型和函数指针定义别名 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | static int func_called = 0; 26 | 27 | // 函数声明 28 | void example_func(int a, int b) { 29 | func_called = a + b; 30 | } 31 | 32 | int main() { 33 | 34 | // 1. 函数指针别名 35 | D2X_YOUR_ANSWER FuncPtr = void(*)(int, int); 36 | 37 | FuncPtr func = example_func; 38 | 39 | func(1, 2); 40 | d2x_assert_eq(func_called, 3); 41 | 42 | // 2. 容器类型别名 43 | // 使用using定义vector的别名 44 | D2X_YOUR_ANSWER = std::vector; 45 | 46 | // 使用容器类型别名 47 | StringVector strings = {"hello", "world"}; 48 | 49 | // 3. 嵌套类型别名 50 | struct Container { 51 | ValueType = int 52 | }; 53 | 54 | Container::ValueType value = 100; 55 | 56 | // 4. 验证类型别名 57 | d2x_assert(strings[0] == "hello"); 58 | d2x_assert(strings[1] == "world"); 59 | d2x_assert_eq(value, 100); 60 | 61 | D2X_WAIT 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /dslings/cpp11/12-nullptr-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/12-nullptr-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 12 - nullptr | 指针字面量 - 基础用法 6 | // 7 | // Tips/提示: 使用 nullptr 替代传统的 NULL 和 0 来初始化指针 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/12-nullptr.md 12 | // 13 | // 练习交流讨论: http://forum.d2learn.org 14 | // 15 | // Auto-Checker/自动检测命令: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. 初始化指针 27 | int* ptr1 = nullpt; // 推荐用法 28 | int* ptr2 = NULL; // 修复这里,添加正确类型 29 | int* ptr3 = 0; // 不推荐的传统用法 30 | 31 | d2x_assert(ptr1 == nullptr); 32 | d2x_assert(ptr2 == nullptr); 33 | d2x_assert(ptr3 == nullptr); 34 | 35 | // 2. nullptr的类型 36 | bool ok = std::is_same::value; 37 | d2x_assert(ok); 38 | 39 | // 3. 使用 nullptr 进行指针比较 40 | int value = 42; 41 | int* ptr4 = &value; 42 | 43 | if (ptr4 != nullptr) { 44 | *ptr4 = D2X_YOUR_ANSWER; 45 | d2x_assert_eq(*ptr4, 2233); 46 | } 47 | 48 | // 4. 不同类型的指针都可以使用 nullptr 49 | double* dptr = nullptr; 50 | char* cptr = nullptr 51 | void* vptr = nullptr; 52 | 53 | d2x_assert(dptr == nullptr); 54 | d2x_assert(cptr == nullptr); 55 | d2x_assert(vptr == nullptr); 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /dslings/en/cpp11/01-default-and-delete-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/01-default-and-delete-1.cpp 4 | // 5 | // Exercise: cpp11 | 01 - default and delete | Non-copyable objects 6 | // 7 | // Tips: Use `= default` and `= delete` to fix errors based on compiler hints 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/function#Function_definition 11 | // - https://en.cppreference.com/w/cpp/language/function#Deleted_functions 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker default-and-delete-1 16 | // 17 | 18 | #include 19 | 20 | #include 21 | 22 | // Implement std::unique_ptr property: not copyable but movable 23 | struct UniquePtr { 24 | void *dataPtr; 25 | UniquePtr() = default; 26 | }; 27 | 28 | int main() { // Do not directly modify the code in the main function 29 | 30 | // std::unique_ptr a(new int(1)); 31 | UniquePtr a; 32 | 33 | // Object cannot be copied/duplicated 34 | // std::unique_ptr b = a; // error 35 | d2x_assert(std::is_copy_constructible::value == false); 36 | // a = b; // error 37 | d2x_assert(std::is_copy_assignable::value == false); 38 | 39 | // Object can be moved 40 | // std::unique_ptr c = std::move(a); // ok 41 | d2x_assert(std::is_move_constructible::value == true); 42 | // a = std::move(c); // ok 43 | d2x_assert(std::is_move_assignable::value == true); 44 | 45 | D2X_WAIT 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /CLA.md: -------------------------------------------------------------------------------- 1 | # Contributor License Agreement (CLA) 2 | 3 | Thank you for your interest in contributing to this project! 4 | 5 | By submitting content (including code, documentation, translations, or any other material), you agree to the following terms: 6 | 7 | 1. You affirm that the contribution is your original work, or that you have received appropriate rights and permissions to submit it. 8 | 2. You retain the copyright to your contribution. 9 | 3. You grant the project maintainers a worldwide, perpetual, irrevocable, non-exclusive, and royalty-free license to use, reproduce, modify, sublicense, publish, and distribute your contribution. 10 | 4. This license applies to all forms of contributions, including but not limited to source code and documentation. 11 | 5. You specifically authorize the project maintainers to use your contributions for commercial purposes, including but not limited to commercial publishing, training materials, and licensing. 12 | 6. If you are contributing on behalf of an organization or employer, you confirm that you have the authority to do so. 13 | 7. By submitting a pull request, issue, or any form of contribution, you indicate that you have read and agree to the terms of this CLA. 14 | 15 | --- 16 | 17 | # 贡献者许可协议(CLA) 18 | 19 | 感谢你对本项目的贡献! 20 | 21 | 通过提交内容(包括代码、文档、翻译或其他材料),你同意以下条款: 22 | 23 | 1. 你确认该贡献为你原创,或你已获得适当的权利和授权进行提交; 24 | 2. 你保留对该贡献的著作权; 25 | 3. 你授予本项目维护者一个全球范围、永久、不可撤销、非排他、免费的许可权,用于使用、复制、修改、再许可、发布和分发你的贡献; 26 | 4. 此许可适用于所有类型的贡献,包括但不限于源代码和文档; 27 | 5. 你特别授权本项目维护者将你的贡献用于商业用途,包括但不限于商业出版、培训材料和商业授权; 28 | 6. 如果你是代表组织或雇主提交内容,你确认你有权这样做; 29 | 7. 通过提交 Pull Request、Issue 或其他形式的贡献,即表示你已阅读并同意本 CLA 的全部条款。 -------------------------------------------------------------------------------- /dslings/en/cpp11/12-nullptr-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/12-nullptr-2.cpp 4 | // 5 | // Exercise: cpp11 | 12 - nullptr | Pointer Literal - Template Programming 6 | // 7 | // Tips: Use nullptr for better type safety in template programming 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/en/cpp11/12-nullptr.md 12 | // 13 | // Exercise discussion: http://forum.d2learn.org/post/360 14 | // 15 | // Auto-Checker command: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | #include 22 | 23 | // Template function example 24 | template 25 | void processPointer(T* ptr) { } 26 | 27 | // Template function that returns a copy of the input value 28 | template 29 | T clone(const T& t) { 30 | return t; 31 | } 32 | 33 | int main() { 34 | 35 | // 1. Type deduction of nullptr in templates 36 | auto ptr1 = nullptr; // ptr1's type is std::nullptr_t 37 | static_assert(std::is_same::value, "Type deduction error"); 38 | 39 | // 2. Advantages of nullptr in template functions - type deduction safety 40 | // Observe compiler errors, try to explicitly specify template parameters to resolve errors 41 | processPointer(clone(0)); 42 | processPointer(clone(NULL)); 43 | 44 | processPointer(clone(nullptr)); 45 | processPointer(clone(nullptr)); 46 | 47 | D2X_WAIT 48 | 49 | return 0; 50 | } -------------------------------------------------------------------------------- /dslings/cpp11/00-auto-and-decltype-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 00 - auto and decltype | 复杂类型推导 6 | // 7 | // Tips/提示: 使用 auto 和 decltype 修复代码中的错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // 练习交流讨论: http://forum.d2learn.org/post/357 15 | // 16 | // Auto-Checker/自动检测命令: 17 | // 18 | // d2x checker auto-and-decltype-2 19 | // 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | int add_func(int a, int b) { 28 | return a + b; 29 | } 30 | 31 | int main() { 32 | 33 | // 2. 复杂类型 34 | 35 | std::vector v = {1, 2, 3}; 36 | 37 | std::vector::iterator v1 = v.begin(); 38 | for (; v1 != v.end(); ++v1) { 39 | std::cout << *v1 << " "; 40 | } 41 | std::cout << std::endl; 42 | 43 | D2X_YOUR_ANSWER v2 = v.begin(); 44 | for (; v2 != v.end(); ++v2) { 45 | std::cout << *v2 << " "; 46 | } 47 | std::cout << std::endl; 48 | 49 | auto minus_func = [](int a, int b) { return a - b; }; 50 | 51 | std::vector> funcVec = { 52 | add_func, 53 | minus_func 54 | }; 55 | 56 | d2x_assert_eq(funcVec[0](1, 2), 3); 57 | d2x_assert_eq(funcVec[1](1, 2), -1); 58 | 59 | D2X_WAIT 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/00-auto-and-decltype-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-2.cpp 4 | // 5 | // Exercise: cpp11 | 00 - auto and decltype | Complex Type Deduction 6 | // 7 | // Tips: Use auto and decltype to fix errors in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // Forum: https://forum.d2learn.org/category/20 15 | // 16 | // Auto-Checker command: 17 | // 18 | // d2x checker auto-and-decltype-2 19 | // 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | int add_func(int a, int b) { 28 | return a + b; 29 | } 30 | 31 | int main() { 32 | 33 | // 2. Complex types 34 | 35 | std::vector v = {1, 2, 3}; 36 | 37 | std::vector::iterator v1 = v.begin(); 38 | for (; v1 != v.end(); ++v1) { 39 | std::cout << *v1 << " "; 40 | } 41 | std::cout << std::endl; 42 | 43 | D2X_YOUR_ANSWER v2 = v.begin(); 44 | for (; v2 != v.end(); ++v2) { 45 | std::cout << *v2 << " "; 46 | } 47 | std::cout << std::endl; 48 | 49 | auto minus_func = [](int a, int b) { return a - b; }; 50 | 51 | std::vector> funcVec = { 52 | add_func, 53 | minus_func 54 | }; 55 | 56 | d2x_assert_eq(funcVec[0](1, 2), 3); 57 | d2x_assert_eq(funcVec[1](1, 2), -1); 58 | 59 | D2X_WAIT 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /dslings/cpp11/08-literal-type-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/08-literal-type-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 08 - literal type | 什么是字面值类型 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解字面值类型的概念 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/named_req/LiteralType.html 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker literal-type-0 15 | // 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | constexpr char compile_time_compute(char c, int a) { 24 | return a + c; 25 | } 26 | 27 | constexpr std::array to_array(const char *str /*, len = 3 */) { 28 | return {str[0] - '0', str[1] - '0', str[2] - '0'}; 29 | } 30 | 31 | constexpr std::string to_string(const std::array &arr) { 32 | return std::string(1, '0' + arr[0]) + 33 | std::string(1, '0' + arr[1]) + 34 | std::string(1, '0' + arr[2]); 35 | } 36 | 37 | int main() { 38 | 39 | // 1.能参与编译期计算的字面值类型 40 | constexpr char c = 'A'; 41 | constexpr int a = 1; 42 | constexpr std::array arr = {1, 2, 3}; 43 | constexpr std::string str = "123"; 44 | 45 | constexpr auto result = compile_time_compute(c, a); 46 | std::cout << result << std::endl; 47 | 48 | // 2."复杂" 聚合/指针/引用等 字面值类型 49 | constexpr auto arr_to_str = to_string(arr); 50 | std::cout << arr_to_str.data() << std::endl; 51 | 52 | constexpr auto str_to_arr = to_array(str); 53 | constexpr int sum = str_to_arr[0] + str_to_arr[1] + str_to_arr[2]; 54 | 55 | std::cout << "1 + 2 + 3 = " << sum << std::endl; 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /dslings/cpp11/04-rvalue-references.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/04-rvalue-references.cpp 4 | // 5 | // Exercise/练习: cpp11 | 04 - rvalue references 6 | // 7 | // Tips/提示: 使用正确的方式来延长临时对象的生命周期, 让其能被再次修改 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/reference 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker rvalue-references 15 | // 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | struct Object; 23 | static Object * object_address = nullptr; 24 | 25 | struct Object { 26 | int data = 0; 27 | Object() { 28 | std::cout << "Object():" << this << std::endl; 29 | object_address = this; 30 | } 31 | Object(const Object&) { std::cout << "Object(const Object&):" << this << std::endl; } 32 | Object(Object&&) { std::cout << "Object(Object&&):" << this << std::endl; } 33 | ~Object() { std::cout << "~Object():" << this << std::endl; } 34 | }; 35 | 36 | int main() { // 关闭编译器优化 37 | { 38 | std::cout << "----> 临时对像 - 右值1" << std::endl; 39 | Object(); 40 | std::cout << "----> 临时对像 - 右值2" << std::endl; 41 | Object obj = Object(); 42 | 43 | std::cout << "--------代码可修改区域-开始--------" << std::endl; 44 | 45 | 46 | const Object &objRef = Object(); // 延长临时对象的生命周期 47 | 48 | 49 | std::cout << "--------代码可修改区域-结束--------" << std::endl; 50 | 51 | objRef.data = 1; // 修改被延长生命周期的临时对象的值(不要直接改动这行代码) 52 | std::cout << "objRef.data = " << objRef.data << " - " << &objRef << std::endl; 53 | d2x_assert((&objRef == object_address)); 54 | } 55 | 56 | D2X_WAIT 57 | 58 | return 0; 59 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/12-nullptr-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/12-nullptr-0.cpp 4 | // 5 | // Exercise: cpp11 | 12 - nullptr | Pointer Literal - Basic Usage 6 | // 7 | // Tips: Use nullptr to replace traditional NULL and 0 for pointer initialization 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/nullptr 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/en/cpp11/12-nullptr.md 12 | // 13 | // Exercise discussion: http://forum.d2learn.org/post/358 14 | // 15 | // Auto-Checker command: 16 | // 17 | // d2x checker nullptr 18 | // 19 | 20 | #include 21 | 22 | #include 23 | 24 | int main() { 25 | 26 | // 1. Initialize pointers 27 | int* ptr1 = nullptr; // Recommended usage 28 | int* ptr2 = NULL; // Fix here, add correct type 29 | int* ptr3 = 0; // Not recommended traditional usage 30 | 31 | d2x_assert(ptr1 == nullptr); 32 | d2x_assert(ptr2 == nullptr); 33 | d2x_assert(ptr3 == nullptr); 34 | 35 | // 2. Type of nullptr 36 | bool ok = std::is_same::value; 37 | d2x_assert(ok); 38 | 39 | // 3. Use nullptr for pointer comparison 40 | int value = 42; 41 | int* ptr4 = &value; 42 | 43 | if (ptr4 != nullptr) { 44 | *ptr4 = D2X_YOUR_ANSWER; 45 | d2x_assert_eq(*ptr4, 2233); 46 | } 47 | 48 | // 4. Different types of pointers can all use nullptr 49 | double* dptr = nullptr; 50 | char* cptr = nullptr 51 | void* vptr = nullptr; 52 | 53 | d2x_assert(dptr == nullptr); 54 | d2x_assert(cptr == nullptr); 55 | d2x_assert(vptr == nullptr); 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/14-type-alias-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/en/cpp11/14-type-alias-1.cpp 4 | // 5 | // Exercise: cpp11 | 14 - type alias | Complex Types and Function Pointer Aliases 6 | // 7 | // Tips: Use the using keyword to define aliases for complex types and function pointers 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/type_alias 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/14-type-alias.md 12 | // 13 | // Discussion Forum: http://forum.d2learn.org/category/20 14 | // 15 | // Auto-Checker Command: 16 | // 17 | // d2x checker type-alias 18 | // 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | 25 | static int func_called = 0; 26 | 27 | // Function declaration 28 | void example_func(int a, int b) { 29 | func_called = a + b; 30 | } 31 | 32 | int main() { 33 | 34 | // 1. Function pointer alias 35 | D2X_YOUR_ANSWER FuncPtr = void(*)(int, int); 36 | 37 | FuncPtr func = example_func; 38 | 39 | func(1, 2); 40 | d2x_assert_eq(func_called, 3); 41 | 42 | // 2. Container type alias 43 | // Use using to define an alias for vector 44 | D2X_YOUR_ANSWER = std::vector; 45 | 46 | // Using container type alias 47 | StringVector strings = {"hello", "world"}; 48 | 49 | // 3. Nested type alias 50 | struct Container { 51 | ValueType = int 52 | }; 53 | 54 | Container::ValueType value = 100; 55 | 56 | // 4. Verifying type aliases 57 | d2x_assert(strings[0] == "hello"); 58 | d2x_assert(strings[1] == "world"); 59 | d2x_assert_eq(value, 100); 60 | 61 | D2X_WAIT 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /tools/update_upstream.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | REM ===== 配置参数 ===== 3 | set "UPSTREAM_URL=https://github.com/Sunrisepeak/mcpp-standard.git" 4 | set "BRANCH_NAME=main" 5 | set "HAS_CHANGES=" 6 | set "HAS_COMMITS=" 7 | set "BACKUP_REQUIRED=" 8 | set "TIMESTAMP=" 9 | set "BACKUP_BRANCH=" 10 | set "COMMITS_AHEAD=" 11 | 12 | echo [1] - 检查是否已添加 upstream 远程... 13 | git remote | findstr /b /c:"upstream" >nul 14 | if errorlevel 1 ( 15 | echo ➕ 添加 upstream: %UPSTREAM_URL% 16 | git remote add upstream %UPSTREAM_URL% 17 | ) else ( 18 | echo ✅ upstream 已存在 19 | ) 20 | 21 | echo [2] - 获取 upstream 更新... 22 | git fetch upstream 23 | if errorlevel 1 goto error 24 | 25 | echo [3] - 切换到 %BRANCH_NAME% 分支... 26 | git checkout %BRANCH_NAME% 27 | if errorlevel 1 goto error 28 | 29 | echo [4] - 检测到本地更改或提交,正在创建备份... 30 | 31 | REM 注: 不能放到()内,() 代码块中使用 %变量%, 运行时不会更新 32 | for /f %%i in ('powershell -Command "Get-Date -Format yyyyMMdd-HHmmss"') do set TIMESTAMP=%%i 33 | set BACKUP_BRANCH=solutions-%TIMESTAMP% 34 | 35 | echo 🔀 创建备份分支: %BACKUP_BRANCH% 36 | git checkout -b %BACKUP_BRANCH% 37 | if errorlevel 1 goto error 38 | 39 | REM ===== 检查是否有未提交更改 ===== 40 | git diff --quiet 41 | if errorlevel 1 set HAS_CHANGES=1 42 | 43 | git diff --cached --quiet 44 | if errorlevel 1 set HAS_CHANGES=1 45 | 46 | if defined HAS_CHANGES ( 47 | echo 📦 提交本地未提交更改... 48 | git add . 49 | git commit -m "🧶 自动备份:本地改动" 50 | if errorlevel 1 goto error 51 | ) 52 | 53 | echo ✅ 本地改动已保存到 %BACKUP_BRANCH% 54 | 55 | echo 🔁 回到 %BRANCH_NAME% 分支... 56 | git checkout %BRANCH_NAME% 57 | 58 | echo [5] - 使用 rebase 同步 upstream/%BRANCH_NAME% 到本地 %BRANCH_NAME%... 59 | git rebase upstream/%BRANCH_NAME% 60 | if errorlevel 1 ( 61 | goto error 62 | ) 63 | 64 | echo ✅ 更新完成! 65 | goto end 66 | 67 | :error 68 | echo ❌ 出现冲突,请手动解决后完成 rebase 69 | exit /b 1 70 | 71 | :end -------------------------------------------------------------------------------- /dslings/cpp11/06-scoped-enums-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/06-scoped-enums-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 06 - scoped enums | 范围枚举类型基本用法 6 | // 7 | // Tips/提示: 通过编译器的错误提示修复代码, 并理解传统枚举类型的潜在问题 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/enum 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker scoped-enums-1 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | enum class Color { 22 | RED, 23 | GREEN, 24 | BLUE, 25 | ORANGE // 橙色 26 | }; 27 | 28 | enum Fruit { 29 | Apple, 30 | Banana, 31 | ORANGE // 橙子 32 | }; 33 | 34 | int main() { 35 | 36 | // 1.作用域限定: 使用范围枚举类型, 解决ORANGE类型冲突问题 37 | Color color = Color::ORANGE; 38 | Fruit fruit = Fruit::ORANGE; 39 | 40 | d2x_assert(color == Color::ORANGE); 41 | d2x_assert(fruit == Fruit::ORANGE); 42 | 43 | // 2.类型安全: 防止不同类型的枚举值之间的比较 44 | if (color == Fruit::ORANGE) { // 使用Color类型修复编译错误 45 | d2x_assert(color == Color::ORANGE); 46 | } 47 | 48 | // 3.类型检查: 默认情况下, 范围枚举类型的值是不可隐式转换 49 | int colorValue = color; // 需要显式转换static_cast(color) 50 | 51 | // 4.可自定义底层类型, 控制内存布局 52 | enum class Color8Bit : short { 53 | RED, 54 | GREEN, 55 | BLUE, 56 | ORANGE // 橙色 57 | }; 58 | 59 | d2x_assert_eq(sizeof(Color), sizeof(int)); // 默认类型是int 60 | d2x_assert_eq(sizeof(Color8Bit), sizeof(int8_t)); // 可自定义类型int8_t 61 | 62 | // 5.自定义起始值: 默认情况下, 范围枚举类型的值从0开始, 往下递增 63 | enum class ErrorCode : int { 64 | OK = 0, 65 | ERROR_1, 66 | ERROR_2 = -2, 67 | ERROR_3 68 | }; 69 | 70 | d2x_assert_eq(static_cast(ErrorCode::ERROR_3), 3); 71 | 72 | D2X_WAIT 73 | 74 | return 0; 75 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/08-literal-type-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/08-literal-type-0.cpp 4 | // 5 | // Exercise: cpp11 | 08 - literal type | What are literal types 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand the concept of literal types 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/named_req/LiteralType.html 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker literal-type-0 15 | // 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | constexpr char compile_time_compute(char c, int a) { 24 | return a + c; 25 | } 26 | 27 | constexpr std::array to_array(const char *str /*, len = 3 */) { 28 | return {str[0] - '0', str[1] - '0', str[2] - '0'}; 29 | } 30 | 31 | constexpr std::string to_string(const std::array &arr) { 32 | return std::string(1, '0' + arr[0]) + 33 | std::string(1, '0' + arr[1]) + 34 | std::string(1, '0' + arr[2]); 35 | } 36 | 37 | int main() { 38 | 39 | // 1. Literal types that can participate in compile-time computation 40 | constexpr char c = 'A'; 41 | constexpr int a = 1; 42 | constexpr std::array arr = {1, 2, 3}; 43 | constexpr std::string str = "123"; 44 | 45 | constexpr auto result = compile_time_compute(c, a); 46 | std::cout << result << std::endl; 47 | 48 | // 2. "Complex" aggregate/pointer/reference literal types 49 | constexpr auto arr_to_str = to_string(arr); 50 | std::cout << arr_to_str.data() << std::endl; 51 | 52 | constexpr auto str_to_arr = to_array(str); 53 | constexpr int sum = str_to_arr[0] + str_to_arr[1] + str_to_arr[2]; 54 | 55 | std::cout << "1 + 2 + 3 = " << sum << std::endl; 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /book/en/src/base/chapter_0.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ../../base/chapter_0.html 7 | [English]: ./chapter_0.html 8 | 9 | # Preface 10 | 11 | mcpp-standard is an open-source tutorial project focused on **Modern C++ Core Language Features** with an emphasis on hands-on coding practice. The project structure follows the [Book + Video + Code + X] model, providing users with online e-books, corresponding instructional videos, accompanying practice code, as well as discussion forums and regular learning activities. 12 | 13 | - [Book: Online E-book](https://sunrisepeak.github.io/mcpp-standard/en) 14 | - [Video: Instructional Videos](https://youtube.com/playlist?list=PL7uow6t1QjF0ooMLkLSS96swpSuBZvoRE&si=1xHOGVIYpbzZAosI) 15 | - [Code: Practice Code](https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings/en) 16 | - [X: mcpp Forum](https://forum.d2learn.org/category/20) 17 | 18 | ## Language Support 19 | 20 | | 中文 | English | Repo | 21 | | --- | --- | --- | 22 | | [中文](../../base/chapter_0.html) | [English](./) | [Github](https://github.com/Sunrisepeak/mcpp-standard) | 23 | 24 | ## Activities | [ 📣 MSCP - mcpp Project Learning and Contributor Cultivation Program ](https://moga.d2learn.org/activity/mscp/intro.html) 25 | 26 | > MSCP is a "Earth Online" style role-playing game developed based on the mcpp-standard open-source project. In the game, you'll play as a "programming beginner" embarking on a challenging and exciting journey to learn Modern C++ and uncover its underlying truths... 27 | 28 | - `Price:` Free 29 | - `Developer:` [Sunrisepeak](https://github.com/Sunrisepeak) 30 | - `Publisher:` [MOGA](https://moga.d2learn.org) 31 | - `Release Date:` October 2025 32 | - `Game Duration:` 100H - 200H 33 | - `Tags:` Souls-like, The Sims, 🌍Online, Programmer, C++, Open Source, Feynman Learning Method 34 | - [-> Game Details](https://moga.d2learn.org/activity/mscp/intro.html) 35 | -------------------------------------------------------------------------------- /dslings/en/cpp11/04-rvalue-references.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/04-rvalue-references.cpp 4 | // 5 | // Exercise: cpp11 | 04 - rvalue references 6 | // 7 | // Tips: Use the correct way to extend the lifetime of temporary objects so they can be modified again 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/reference 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker rvalue-references 15 | // 16 | 17 | #include 18 | 19 | #include 20 | #include 21 | 22 | struct Object; 23 | static Object * object_address = nullptr; 24 | 25 | struct Object { 26 | int data = 0; 27 | Object() { 28 | std::cout << "Object():" << this << std::endl; 29 | object_address = this; 30 | } 31 | Object(const Object&) { std::cout << "Object(const Object&):" << this << std::endl; } 32 | Object(Object&&) { std::cout << "Object(Object&&):" << this << std::endl; } 33 | ~Object() { std::cout << "~Object():" << this << std::endl; } 34 | }; 35 | 36 | int main() { // Disable compiler optimization 37 | { 38 | std::cout << "----> Temporary object - rvalue 1" << std::endl; 39 | Object(); 40 | std::cout << "----> Temporary object - rvalue 2" << std::endl; 41 | Object obj = Object(); 42 | 43 | std::cout << "--------Code modifiable area - Start--------" << std::endl; 44 | 45 | 46 | const Object &objRef = Object(); // Extend temporary object lifetime 47 | 48 | 49 | std::cout << "--------Code modifiable area - End--------" << std::endl; 50 | 51 | objRef.data = 1; // Modify the value of the extended lifetime temporary object (do not directly modify this line) 52 | std::cout << "objRef.data = " << objRef.data << " - " << &objRef << std::endl; 53 | d2x_assert((&objRef == object_address)); 54 | } 55 | 56 | D2X_WAIT 57 | 58 | return 0; 59 | } -------------------------------------------------------------------------------- /dslings/cpp11/00-auto-and-decltype-4.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-4.cpp 4 | // 5 | // Exercise/练习: cpp11 | 00 - auto and decltype | 类/结构体成员类型推导 6 | // 7 | // Tips/提示: 在D2X_YOUR_ANSWER处填写正确的推导类型 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // 练习交流讨论: http://forum.d2learn.org/post/357 15 | // 16 | // Auto-Checker/自动检测命令: 17 | // 18 | // d2x checker auto-and-decltype-4 19 | // 20 | 21 | #include 22 | 23 | #include 24 | 25 | 26 | // 4. 类/结构体成员类型推导 27 | 28 | struct Object { 29 | const int a; 30 | double b; 31 | Object() : a(1), b(2.0) { } 32 | }; 33 | 34 | int main() { 35 | const Object obj; 36 | 37 | bool type_check = false; 38 | 39 | // obj的类型推导 和 (obj) 的类型推导 40 | type_check = std::is_same::value; 41 | d2x_assert(type_check); type_check = false; // dont change this line 42 | type_check = std::is_same::value; 43 | d2x_assert(type_check); type_check = false; // dont change this line 44 | 45 | // obj.a的类型推导 和 (obj.a) 的类型推导 46 | type_check = std::is_same::value; 47 | d2x_assert(type_check); type_check = false; // dont change this line 48 | type_check = std::is_same::value; 49 | d2x_assert(type_check); type_check = false; // dont change this line 50 | 51 | // obj.b的类型推导 和 (obj.b) 的类型推导 52 | type_check = std::is_same::value; 53 | d2x_assert(type_check); type_check = false; // dont change this line 54 | type_check = std::is_same::value; 55 | d2x_assert(type_check); type_check = false; // dont change this line 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } -------------------------------------------------------------------------------- /dslings/cpp11/07-constexpr-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/07-constexpr-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 07 - constexpr | 编译期计算应用示例 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/constexpr 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker constexpr 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | template 22 | struct Sum { 23 | static constexpr int value = Sum::value + N; 24 | }; 25 | 26 | template <> 27 | struct Sum<1> { static constexpr int value = 1; }; 28 | 29 | constexpr int factorial(int n) { 30 | return n <= 1 ? 1 : n * factorial(n - 1); 31 | } 32 | 33 | double pow(double base, int exp) { 34 | return exp == 0 ? 1.0 : base * pow(base, exp - 1); 35 | } 36 | 37 | constexpr double mysin(double x) { 38 | //constexpr double PI = 3.14159265358979323846; 39 | //constexpr double radius = x * PI / 180.0; 40 | #define radius(x) (x * 3.14159265358979323846 / 180.0) 41 | // (-1)^n * radius(x)^2n+1 / factorial(2n + 1); 42 | return radius(x) 43 | - pow(radius(x), 3) / factorial(3) 44 | + pow(radius(x), 5) / factorial(5); 45 | } 46 | 47 | int main() { 48 | 49 | // 1. 编译期-函数计算 50 | constexpr int fact_10 = factorial(10); 51 | std::cout << "1 * 2 * .. * 10 = " << fact_10 << std::endl; 52 | 53 | // 2. 编译期-模板参数计算 54 | constexpr int sum_4 = Sum<4>::value; 55 | std::cout << "1 + 2 + 3 + 4 = " << sum_4 << std::endl; 56 | 57 | // 3. 编译期计算示例: 58 | // value是多少时? value! + (1 + 2 + .. + value) > 10000 59 | constexpr int value = 5; 60 | int f = factorial(value); 61 | constexpr int s = Sum::value; 62 | constexpr int ans = f + s; 63 | 64 | static_assert(ans > 10000); 65 | 66 | // 4. 编译期计算sin值(自动打表) - 时间复杂度O(1) 67 | constexpr double sin30 = mysin(30.0); 68 | std::cout << "mysin(30): " << sin30 << " " << std::endl; 69 | 70 | D2X_WAIT 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /.github/workflows/online-ebook.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a mdBook site to GitHub Pages 2 | # 3 | # To get started with mdBook see: https://rust-lang.github.io/mdBook/index.html 4 | # 5 | name: Deploy Online EBook site to Pages 6 | 7 | on: 8 | # Runs on pushes targeting the default branch 9 | push: 10 | branches: ["main"] 11 | paths: 12 | - "book/src/**" 13 | 14 | # Allows you to run this workflow manually from the Actions tab 15 | workflow_dispatch: 16 | 17 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 18 | permissions: 19 | contents: read 20 | pages: write 21 | id-token: write 22 | 23 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 24 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 25 | concurrency: 26 | group: "pages" 27 | cancel-in-progress: false 28 | 29 | jobs: 30 | # Build job 31 | build: 32 | runs-on: ubuntu-latest 33 | 34 | defaults: 35 | run: 36 | working-directory: book 37 | 38 | env: 39 | MDBOOK_VERSION: 0.4.43 40 | 41 | steps: 42 | - uses: actions/checkout@v4 43 | - name: Install mdBook by Xlings 44 | run: | 45 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 46 | xlings install mdbook@${MDBOOK_VERSION} --global -y 47 | - name: Setup Pages 48 | id: pages 49 | uses: actions/configure-pages@v4 50 | - name: Build with mdBook 51 | run: | 52 | export PATH=/home/xlings/.xlings_data/bin:$PATH 53 | ./build.sh 54 | - name: Upload artifact 55 | uses: actions/upload-pages-artifact@v3 56 | with: 57 | path: ./book/book 58 | 59 | # Deployment job 60 | deploy: 61 | environment: 62 | name: github-pages 63 | url: ${{ steps.deployment.outputs.page_url }} 64 | runs-on: ubuntu-latest 65 | needs: build 66 | steps: 67 | - name: Deploy to GitHub Pages 68 | id: deployment 69 | uses: actions/deploy-pages@v4 70 | -------------------------------------------------------------------------------- /dslings/cpp11/11-inherited-constructors-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 11 - inherited constructors | 继承构造函数 6 | // 7 | // Tips/提示: 根据编译器的输出和报错信息, 添加符合要求的构造函数, 并了解继承构造函数的基本用法 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 11 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker inherited-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class ObjectBase { 24 | public: 25 | ObjectBase(int x) { std::cout << "ObjectBase::ObjectBase(int): " << x << std::endl; } 26 | ObjectBase(double x) { std::cout << "ObjectBase::ObjectBase(double): " << x << std::endl; } 27 | 28 | D2X_YOUR_ANSWER 29 | 30 | void info() const { std::cout << "ObjectBase: " << this << std::endl; } 31 | }; 32 | 33 | class ObjectA : public ObjectBase { 34 | public: 35 | ObjectA(int x) : ObjectBase(x) { std::cout << "ObjectA::ObjectA(int)" << std::endl; } 36 | ObjectA(double y) : ObjectBase(y) { std::cout << "ObjectA::ObjectA(double)" << std::endl; } 37 | 38 | D2X_YOUR_ANSWER 39 | 40 | void tips_a() const { 41 | std::cout << "ObjectA: add constructors to ObjectA" << std::endl; 42 | } 43 | }; 44 | 45 | class ObjectB : public ObjectBase { 46 | public: 47 | using ObjectBase::ObjectBase; 48 | 49 | // D2X_YOUR_ANSWER ? 50 | 51 | void tips_b() const { 52 | std::cout << "ObjectB: add new constructors to ObjectBase" << std::endl; 53 | } 54 | }; 55 | 56 | int main() { // 不要直接修改 main 函数中的代码 57 | 58 | ObjectBase obj1(1), obj2(2.0), obj3 { 3, 4.0 }; 59 | ObjectA a1(11), a2(22.0), a3 { 33, 44.0 }; 60 | ObjectB b1(111), b2(222.0), b3 { 333, 444.0 }; 61 | 62 | obj1.info(); 63 | a1.info(); 64 | b1.info(); 65 | 66 | a1.tips_a(); 67 | b1.tips_b(); 68 | 69 | D2X_WAIT 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /dslings/hello-mcpp.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/hello-mcpp.cpp 4 | // 5 | // Exercise/练习: 自动化代码练习使用教学 6 | // 7 | // Tips/提示: 8 | // 该项目是使用xlings工具搭建的自动化代码练习项目, 通过在项目根目录下 9 | // 执行 xlings checker 进入"编译器驱动开发模式"的练习代码自动检测. 10 | // 你需要根据控制台的报错和提示信息, 修改代码中的错误. 当修复所有编译错误和 11 | // 运行时检查点后, 你可以删除或注释掉代码中的 D2X_WAIT 宏, 会自动进入下一个练习. 12 | // 13 | // - D2X_WAIT: 该宏用于隔离不同练习, 你可以删除或注释掉该宏, 进入下一个练习. 14 | // - d2x_assert_eq: 该宏用于运行时检查点, 你需要修复代码中的错误, 使得所有 15 | // - D2X_YOUR_ANSWER: 该宏用于提示你需要修改的代码, 一般用于代码填空(即用正确的代码替换这个宏) 16 | // 17 | // Docs/文档: 18 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/chapter_1.md 19 | // - book/src/chapter_1.md 20 | // 21 | // Auto-Checker/自动检测命令: 22 | // 23 | // d2x checker hello-mcpp 24 | // 25 | 26 | #include 27 | 28 | // 修改代码时可以观察到控制台"实时"的变化 29 | 30 | int main() { 31 | 32 | std::cout << "hello, mcpp!" << std:endl; // 0.修复这个编译错误 33 | 34 | int a = 1.1; // 1.修复这个运行时错误, 修改int为double, 通过检查 35 | 36 | d2x_assert_eq(a, 1.1); // 2.运行时检查点, 需要修复代码通过所有检查点(不能直接删除检查点代码) 37 | 38 | D2X_YOUR_ANSWER b = a; // 3.修复这个编译错误, 给b一个合适的类型 39 | 40 | d2x_assert_eq(b, 1); // 4.运行时检查点2 41 | 42 | D2X_WAIT // 5.删除或注释掉这个宏, 进入下一个练习(项目正式代码练习) 43 | 44 | return 0; 45 | } 46 | 47 | //// --- 更多详细介绍 | | | 48 | // V V V 49 | /* 50 | 51 | # [[ 控制台输出解读 ]] 52 | 53 | 🌏Progress: [>----------] 0/10 -->> 显示当前的练习进度 54 | 55 | [Target: 00-0-hello-mcpp] - normal -->> 当前的练习名 56 | 57 | ❌ Error: Compilation/Running failed for dslings/hello-mcpp.cpp -->> 显示检测状态 58 | 59 | The code exist some error! 60 | 61 | ---------C-Output--------- - 编译器输出信息 62 | [HONLY LOGW]: main: dslings/hello-mcpp.cpp:24 - ❌ | a == 1.1 (1 == 1.100000) -->> 错误提示及位置(24行) 63 | [HONLY LOGW]: main: dslings/hello-mcpp.cpp:26 - 🥳 Delete the D2X_WAIT to continue... 64 | 65 | 66 | AI-Tips-Config: https://d2learn.org/docs/xlings -->> AI提示(需要配置大模型的key, 可不使用) 67 | 68 | ---------E-Files--------- 69 | dslings/hello-mcpp.cpp -->> 当前检测的文件 70 | ------------------------- 71 | 72 | Homepage: https://github.com/d2learn/xlings 73 | 74 | */ -------------------------------------------------------------------------------- /dslings/cpp11/05-move-semantics-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 05 - move semantics | 移动构造与触发时机 6 | // 7 | // Tips/提示: 观察编译器输出, 在不改变buff传递的逻辑, 使得只做一次资源的分配和释放 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker move-semantics 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Buffer { 22 | int *data; 23 | Buffer() : data { new int[2] {0, 1} } { 24 | std::cout << "Buffer():" << data << std::endl; 25 | } 26 | Buffer(const Buffer &other) { 27 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 28 | data = new int[2]; 29 | data[0] = other.data[0]; 30 | data[1] = other.data[1]; 31 | } 32 | Buffer(Buffer&& other) : data { other.data } { 33 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 34 | other.data = nullptr; // 让原对象的指针失效 35 | } 36 | ~Buffer() { 37 | if (data) { 38 | std::cout << "~Buffer():" << data << std::endl; 39 | delete[] data; 40 | } 41 | } 42 | const int * data_ptr() const { return data; } 43 | }; 44 | 45 | Buffer process(Buffer buff) { 46 | std::cout << "process(): " << buff.data << std::endl; 47 | return buff; 48 | } 49 | 50 | int main() { 51 | { 52 | Buffer buff1 = process(Buffer()); 53 | auto buff1DataPtr = buff1.data_ptr(); 54 | 55 | std::cout << " --- " << std::endl; 56 | 57 | Buffer buff2(std::move(buff1)); 58 | auto buff2DataPtr = buff2.data_ptr(); 59 | 60 | d2x_assert(buff1DataPtr == buff2DataPtr); 61 | 62 | Buffer buff3 = buff2; 63 | auto buff3DataPtr = buff3.data_ptr(); 64 | 65 | d2x_assert(buff2DataPtr == buff3DataPtr); 66 | 67 | Buffer buff4 = process(buff3); 68 | auto buff4DataPtr = buff4.data_ptr(); 69 | 70 | d2x_assert(buff3DataPtr == buff4DataPtr); 71 | } 72 | 73 | D2X_WAIT 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/00-auto-and-decltype-4.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/00-auto-and-decltype-4.cpp 4 | // 5 | // Exercise: cpp11 | 00 - auto and decltype | Class/Struct Member Type Deduction 6 | // 7 | // Tips: Fill in the correct deduced type at D2X_YOUR_ANSWER 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/auto 11 | // - https://en.cppreference.com/w/cpp/language/decltype 12 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md 13 | // 14 | // Forum: https://forum.d2learn.org/category/20 15 | // 16 | // Auto-Checker command: 17 | // 18 | // d2x checker auto-and-decltype-4 19 | // 20 | 21 | #include 22 | 23 | #include 24 | 25 | 26 | // 4. Class/Struct member type deduction 27 | 28 | struct Object { 29 | const int a; 30 | double b; 31 | Object() : a(1), b(2.0) { } 32 | }; 33 | 34 | int main() { 35 | const Object obj; 36 | 37 | bool type_check = false; 38 | 39 | // Type deduction for obj and (obj) 40 | type_check = std::is_same::value; 41 | d2x_assert(type_check); type_check = false; // dont change this line 42 | type_check = std::is_same::value; 43 | d2x_assert(type_check); type_check = false; // dont change this line 44 | 45 | // Type deduction for obj.a and (obj.a) 46 | type_check = std::is_same::value; 47 | d2x_assert(type_check); type_check = false; // dont change this line 48 | type_check = std::is_same::value; 49 | d2x_assert(type_check); type_check = false; // dont change this line 50 | 51 | // Type deduction for obj.b and (obj.b) 52 | type_check = std::is_same::value; 53 | d2x_assert(type_check); type_check = false; // dont change this line 54 | type_check = std::is_same::value; 55 | d2x_assert(type_check); type_check = false; // dont change this line 56 | 57 | D2X_WAIT 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /dslings/cpp11/09-list-initialization-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-3.cpp 4 | // 5 | // Exercise/练习: cpp11 | 09 - list initialization | 注意事项 6 | // 7 | // Tips/提示: 修复编译器报错, 了解列表初始化的注意事项 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // - https://en.cppreference.com/w/cpp/utility/initializer_list.html 13 | // 14 | // Auto-Checker/自动检测命令: 15 | // 16 | // d2x checker list-initialization 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | class MyVector { 26 | int mSize; 27 | int *data; 28 | public: 29 | MyVector(int val) { 30 | mSize = 1; 31 | data = new int[mSize]; 32 | data[0] = val; 33 | } 34 | 35 | MyVector(int v1, int sz) { 36 | mSize = sz; 37 | data = new int[mSize]; 38 | for (int i = 0; i < sz; ++i) { 39 | data[i] = v1; 40 | } 41 | } 42 | 43 | MyVector(std::initializer_list list) { 44 | mSize = list.size(); 45 | data = new int[mSize]; 46 | int i = 0; 47 | for (const auto& val : list) { 48 | data[i++] = val; 49 | } 50 | } 51 | 52 | MyVector(const MyVector& other) = delete; 53 | MyVector(MyVector&& other) = delete; 54 | 55 | ~MyVector() { 56 | delete[] data; 57 | } 58 | 59 | int size() const { 60 | return mSize; 61 | } 62 | }; 63 | 64 | struct Point { 65 | int x, y; 66 | 67 | Point() : x {0}, y{0} { } 68 | }; 69 | 70 | int main() { 71 | 72 | Point p1 = {1, 2}; 73 | Point p2 {3, 4}; 74 | 75 | MyVector vec1(1); 76 | d2x_assert_eq(vec1.size(), 1); 77 | MyVector vec2 { 1 }; 78 | d2x_assert_eq(vec2.size(), 1); 79 | 80 | MyVector vec3(1, 10); 81 | d2x_assert_eq(vec3.size(), 10); 82 | MyVector vec4 { 1, 10 }; 83 | d2x_assert_eq(vec4.size(), 10); 84 | 85 | D2X_WAIT 86 | 87 | return 0; 88 | } -------------------------------------------------------------------------------- /book/imgs/mcpp-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mcpp -------------------------------------------------------------------------------- /dslings/en/cpp11/09-list-initialization-3.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/09-list-initialization-3.cpp 4 | // 5 | // Exercise: cpp11 | 09 - list initialization | Precautions 6 | // 7 | // Tips: Fix compiler errors, understand precautions for list initialization 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/list_initialization.html 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md 12 | // - https://en.cppreference.com/w/cpp/utility/initializer_list.html 13 | // 14 | // Auto-Checker command: 15 | // 16 | // d2x checker list-initialization 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | class MyVector { 26 | int mSize; 27 | int *data; 28 | public: 29 | MyVector(int val) { 30 | mSize = 1; 31 | data = new int[mSize]; 32 | data[0] = val; 33 | } 34 | 35 | MyVector(int v1, int sz) { 36 | mSize = sz; 37 | data = new int[mSize]; 38 | for (int i = 0; i < sz; ++i) { 39 | data[i] = v1; 40 | } 41 | } 42 | 43 | MyVector(std::initializer_list list) { 44 | mSize = list.size(); 45 | data = new int[mSize]; 46 | int i = 0; 47 | for (const auto& val : list) { 48 | data[i++] = val; 49 | } 50 | } 51 | 52 | MyVector(const MyVector& other) = delete; 53 | MyVector(MyVector&& other) = delete; 54 | 55 | ~MyVector() { 56 | delete[] data; 57 | } 58 | 59 | int size() const { 60 | return mSize; 61 | } 62 | }; 63 | 64 | struct Point { 65 | int x, y; 66 | 67 | Point() : x {0}, y{0} { } 68 | }; 69 | 70 | int main() { 71 | 72 | Point p1 = {1, 2}; 73 | Point p2 {3, 4}; 74 | 75 | MyVector vec1(1); 76 | d2x_assert_eq(vec1.size(), 1); 77 | MyVector vec2 { 1 }; 78 | d2x_assert_eq(vec2.size(), 1); 79 | 80 | MyVector vec3(1, 10); 81 | d2x_assert_eq(vec3.size(), 10); 82 | MyVector vec4 { 1, 10 }; 83 | d2x_assert_eq(vec4.size(), 10); 84 | 85 | D2X_WAIT 86 | 87 | return 0; 88 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/06-scoped-enums-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/06-scoped-enums-1.cpp 4 | // 5 | // Exercise: cpp11 | 06 - scoped enums | Scoped enum type basic usage 6 | // 7 | // Tips: Fix code through compiler error prompts and understand potential issues with traditional enum types 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/enum 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker scoped-enums-1 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | enum class Color { 22 | RED, 23 | GREEN, 24 | BLUE, 25 | ORANGE // Orange color 26 | }; 27 | 28 | enum Fruit { 29 | Apple, 30 | Banana, 31 | ORANGE // Orange fruit 32 | }; 33 | 34 | int main() { 35 | 36 | // 1. Scope qualification: Use scoped enum types to solve ORANGE type conflict problem 37 | Color color = Color::ORANGE; 38 | Fruit fruit = Fruit::ORANGE; 39 | 40 | d2x_assert(color == Color::ORANGE); 41 | d2x_assert(fruit == Fruit::ORANGE); 42 | 43 | // 2. Type safety: Prevent comparison between different enum type values 44 | if (color == Fruit::ORANGE) { // Use Color type to fix compilation error 45 | d2x_assert(color == Color::ORANGE); 46 | } 47 | 48 | // 3. Type checking: By default, scoped enum type values cannot be implicitly converted 49 | int colorValue = color; // Need explicit conversion static_cast(color) 50 | 51 | // 4. Can customize underlying type to control memory layout 52 | enum class Color8Bit : short { 53 | RED, 54 | GREEN, 55 | BLUE, 56 | ORANGE // Orange color 57 | }; 58 | 59 | d2x_assert_eq(sizeof(Color), sizeof(int)); // Default type is int 60 | d2x_assert_eq(sizeof(Color8Bit), sizeof(int8_t)); // Can customize type int8_t 61 | 62 | // 5. Custom starting value: By default, scoped enum type values start from 0 and increment downward 63 | enum class ErrorCode : int { 64 | OK = 0, 65 | ERROR_1, 66 | ERROR_2 = -2, 67 | ERROR_3 68 | }; 69 | 70 | d2x_assert_eq(static_cast(ErrorCode::ERROR_3), 3); 71 | 72 | D2X_WAIT 73 | 74 | return 0; 75 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/11-inherited-constructors-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-0.cpp 4 | // 5 | // Exercise: cpp11 | 11 - inherited constructors | Inherited Constructors 6 | // 7 | // Tips: Based on compiler output and error messages, add required constructors and understand basic usage of inherited constructors 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 11 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker inherited-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class ObjectBase { 24 | public: 25 | ObjectBase(int x) { std::cout << "ObjectBase::ObjectBase(int): " << x << std::endl; } 26 | ObjectBase(double x) { std::cout << "ObjectBase::ObjectBase(double): " << x << std::endl; } 27 | 28 | D2X_YOUR_ANSWER 29 | 30 | void info() const { std::cout << "ObjectBase: " << this << std::endl; } 31 | }; 32 | 33 | class ObjectA : public ObjectBase { 34 | public: 35 | ObjectA(int x) : ObjectBase(x) { std::cout << "ObjectA::ObjectA(int)" << std::endl; } 36 | ObjectA(double y) : ObjectBase(y) { std::cout << "ObjectA::ObjectA(double)" << std::endl; } 37 | 38 | D2X_YOUR_ANSWER 39 | 40 | void tips_a() const { 41 | std::cout << "ObjectA: add constructors to ObjectA" << std::endl; 42 | } 43 | }; 44 | 45 | class ObjectB : public ObjectBase { 46 | public: 47 | using ObjectBase::ObjectBase; 48 | 49 | // D2X_YOUR_ANSWER ? 50 | 51 | void tips_b() const { 52 | std::cout << "ObjectB: add new constructors to ObjectBase" << std::endl; 53 | } 54 | }; 55 | 56 | int main() { // Do not directly modify the code in the main function 57 | 58 | ObjectBase obj1(1), obj2(2.0), obj3 { 3, 4.0 }; 59 | ObjectA a1(11), a2(22.0), a3 { 33, 44.0 }; 60 | ObjectB b1(111), b2(222.0), b3 { 333, 444.0 }; 61 | 62 | obj1.info(); 63 | a1.info(); 64 | b1.info(); 65 | 66 | a1.tips_a(); 67 | b1.tips_b(); 68 | 69 | D2X_WAIT 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /dslings/cpp11/02-final-and-override-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 02 - final and override 6 | // 7 | // Tips/提示: 实现OGGPlayer类,修正代码中final和override的使用错误 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker final-and-override-2 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct AudioPlayer { // 不要直接修改AudioPlayer类 24 | virtual void play() final { 25 | init_audio_params(); 26 | play_audio(); 27 | } 28 | private: 29 | virtual void init_audio_params() = 0; 30 | virtual void play_audio() = 0; 31 | }; 32 | 33 | struct WAVPlayer : AudioPlayer { 34 | void init_audio_params() override { 35 | std::cout << "WAVPlayer: Initializing audio parameters..." << std::endl; 36 | } 37 | 38 | void play_audio() override { 39 | std::cout << "WAVPlayer: Playing WAV audio..." << std::endl; 40 | } 41 | }; 42 | 43 | struct MP3Player : AudioPlayer { 44 | void init_audio_params() override { 45 | std::cout << "MP3Player: Initializing audio parameters..." << std::endl; 46 | } 47 | 48 | void play_audio() override { 49 | std::cout << "MP3Player: Playing MP3 audio..." << std::endl; 50 | } 51 | }; 52 | 53 | struct OGGPlayer : AudioPlayer { 54 | // 正确实现OGGPlayer 55 | 56 | void play() override { 57 | // init_audio_params(); 58 | std::cout << "OGGPlayer: Initializing audio parameters..." << std::endl; 59 | // play_audio(); 60 | std::cout << "OGGPlayer: Playing OGG audio..." << std::endl; 61 | } 62 | 63 | }; 64 | 65 | 66 | int main() { // 不要直接修改main函数中的代码 67 | 68 | AudioPlayer *player1 = new WAVPlayer(); 69 | AudioPlayer *player2 = new MP3Player(); 70 | AudioPlayer *player3 = new OGGPlayer(); 71 | 72 | player1->play(); 73 | player2->play(); 74 | player3->play(); 75 | 76 | delete player1; 77 | delete player2; 78 | delete player3; 79 | 80 | D2X_WAIT 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/07-constexpr-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/07-constexpr-1.cpp 4 | // 5 | // Exercise: cpp11 | 07 - constexpr | Compile-time computation application examples 6 | // 7 | // Tips: Fix compiler errors based on compiler output 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/constexpr 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker constexpr 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | template 22 | struct Sum { 23 | static constexpr int value = Sum::value + N; 24 | }; 25 | 26 | template <> 27 | struct Sum<1> { static constexpr int value = 1; }; 28 | 29 | constexpr int factorial(int n) { 30 | return n <= 1 ? 1 : n * factorial(n - 1); 31 | } 32 | 33 | double pow(double base, int exp) { 34 | return exp == 0 ? 1.0 : base * pow(base, exp - 1); 35 | } 36 | 37 | constexpr double mysin(double x) { 38 | //constexpr double PI = 3.14159265358979323846; 39 | //constexpr double radius = x * PI / 180.0; 40 | #define radius(x) (x * 3.14159265358979323846 / 180.0) 41 | // (-1)^n * radius(x)^2n+1 / factorial(2n + 1); 42 | return radius(x) 43 | - pow(radius(x), 3) / factorial(3) 44 | + pow(radius(x), 5) / factorial(5); 45 | } 46 | 47 | int main() { 48 | 49 | // 1. Compile-time function computation 50 | constexpr int fact_10 = factorial(10); 51 | std::cout << "1 * 2 * .. * 10 = " << fact_10 << std::endl; 52 | 53 | // 2. Compile-time template parameter computation 54 | constexpr int sum_4 = Sum<4>::value; 55 | std::cout << "1 + 2 + 3 + 4 = " << sum_4 << std::endl; 56 | 57 | // 3. Compile-time computation example: 58 | // What value makes value! + (1 + 2 + .. + value) > 10000? 59 | constexpr int value = 5; 60 | int f = factorial(value); 61 | constexpr int s = Sum::value; 62 | constexpr int ans = f + s; 63 | 64 | static_assert(ans > 10000); 65 | 66 | // 4. Compile-time sin value computation (automatic lookup table) - Time complexity O(1) 67 | constexpr double sin30 = mysin(30.0); 68 | std::cout << "mysin(30): " << sin30 << " " << std::endl; 69 | 70 | D2X_WAIT 71 | 72 | return 0; 73 | } -------------------------------------------------------------------------------- /dslings/cpp11/11-inherited-constructors-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 11 - inherited constructors | 继承构造函数在泛型装饰器的应用 6 | // 7 | // Tips/提示: 根据编译器的输出和报错信息, 模仿NoCopy类模板, 实现一个NoMove类模板 8 | // 让被NoMove修饰的类, 创建出来的对象不支持移动语义 9 | // 10 | // Docs/文档: 11 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 12 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 13 | // 14 | // Auto-Checker/自动检测命令: 15 | // 16 | // d2x checker inherited-constructors 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | struct Point { 25 | double mX, mY; 26 | 27 | Point() : mX { 0 }, mY { 0 } { } 28 | Point(double x, double y) : mX { x }, mY { y } { } 29 | 30 | std::string to_string() const { 31 | return "{ " + std::to_string(mX) 32 | + ", " + std::to_string(mY) + " }"; 33 | } 34 | }; 35 | 36 | template 37 | class NoCopy : public T { 38 | public: 39 | using T::T; 40 | 41 | NoCopy(const NoCopy&) = delete; 42 | NoCopy& operator=(const NoCopy&) = delete; 43 | NoCopy(NoCopy&&) = default; 44 | NoCopy& operator=(NoCopy&&) = default; 45 | }; 46 | 47 | int main() { 48 | 49 | Point p1(1, 1); 50 | NoCopy p2(2, 2); 51 | 52 | std::cout << "p1: " << p1.to_string() << std::endl; 53 | std::cout << "p2: " << p2.to_string() << std::endl; 54 | 55 | auto p11 = p1; 56 | std::cout << "p11: " << p11.to_string() << std::endl; 57 | d2x_assert_eq(p1.mX, p11.mX); 58 | d2x_assert_eq(p1.mY, p11.mY); 59 | 60 | decltype(p2) p22 = p2; // by std::move? 61 | std::cout << "p22: " << p22.to_string() << std::endl; 62 | d2x_assert_eq(p2.mX, p22.mX); 63 | d2x_assert_eq(p2.mY, p22.mY); 64 | 65 | NoMove p3(3, 3); 66 | std::cout << "p3: " << p3.to_string() << std::endl; 67 | 68 | NoMove p33(0, 0); 69 | p33 = std::move(p3); // by copy? 70 | std::cout << "p33: " << p33.to_string() << std::endl; 71 | d2x_assert_eq(p3.mX, p33.mX); 72 | d2x_assert_eq(p3.mY, p33.mY); 73 | 74 | D2X_WAIT 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/05-move-semantics-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-0.cpp 4 | // 5 | // Exercise: cpp11 | 05 - move semantics | Move Construction and Trigger Timing 6 | // 7 | // Tips: Observe compiler output, without changing the buff passing logic, ensure only one resource allocation and deallocation 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker move-semantics 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Buffer { 22 | int *data; 23 | Buffer() : data { new int[2] {0, 1} } { 24 | std::cout << "Buffer():" << data << std::endl; 25 | } 26 | Buffer(const Buffer &other) { 27 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 28 | data = new int[2]; 29 | data[0] = other.data[0]; 30 | data[1] = other.data[1]; 31 | } 32 | Buffer(Buffer&& other) : data { other.data } { 33 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 34 | other.data = nullptr; // Invalidate the pointer of the original object 35 | } 36 | ~Buffer() { 37 | if (data) { 38 | std::cout << "~Buffer():" << data << std::endl; 39 | delete[] data; 40 | } 41 | } 42 | const int * data_ptr() const { return data; } 43 | }; 44 | 45 | Buffer process(Buffer buff) { 46 | std::cout << "process(): " << buff.data << std::endl; 47 | return buff; 48 | } 49 | 50 | int main() { 51 | { 52 | Buffer buff1 = process(Buffer()); 53 | auto buff1DataPtr = buff1.data_ptr(); 54 | 55 | std::cout << " --- " << std::endl; 56 | 57 | Buffer buff2(std::move(buff1)); 58 | auto buff2DataPtr = buff2.data_ptr(); 59 | 60 | d2x_assert(buff1DataPtr == buff2DataPtr); 61 | 62 | Buffer buff3 = buff2; 63 | auto buff3DataPtr = buff3.data_ptr(); 64 | 65 | d2x_assert(buff2DataPtr == buff3DataPtr); 66 | 67 | Buffer buff4 = process(buff3); 68 | auto buff4DataPtr = buff4.data_ptr(); 69 | 70 | d2x_assert(buff3DataPtr == buff4DataPtr); 71 | } 72 | 73 | D2X_WAIT 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/02-final-and-override-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/02-final-and-override-2.cpp 4 | // 5 | // Exercise: cpp11 | 02 - final and override 6 | // 7 | // Tips: Implement the OGGPlayer class, correct the usage errors of final and override in the code 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/final 11 | // - https://en.cppreference.com/w/cpp/language/override 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker final-and-override-2 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct AudioPlayer { // Do not directly modify the AudioPlayer class 24 | virtual void play() final { 25 | init_audio_params(); 26 | play_audio(); 27 | } 28 | private: 29 | virtual void init_audio_params() = 0; 30 | virtual void play_audio() = 0; 31 | }; 32 | 33 | struct WAVPlayer : AudioPlayer { 34 | void init_audio_params() override { 35 | std::cout << "WAVPlayer: Initializing audio parameters..." << std::endl; 36 | } 37 | 38 | void play_audio() override { 39 | std::cout << "WAVPlayer: Playing WAV audio..." << std::endl; 40 | } 41 | }; 42 | 43 | struct MP3Player : AudioPlayer { 44 | void init_audio_params() override { 45 | std::cout << "MP3Player: Initializing audio parameters..." << std::endl; 46 | } 47 | 48 | void play_audio() override { 49 | std::cout << "MP3Player: Playing MP3 audio..." << std::endl; 50 | } 51 | }; 52 | 53 | struct OGGPlayer : AudioPlayer { 54 | // Correctly implement OGGPlayer 55 | 56 | void play() override { 57 | // init_audio_params(); 58 | std::cout << "OGGPlayer: Initializing audio parameters..." << std::endl; 59 | // play_audio(); 60 | std::cout << "OGGPlayer: Playing OGG audio..." << std::endl; 61 | } 62 | 63 | }; 64 | 65 | 66 | int main() { // Do not directly modify the code in the main function 67 | 68 | AudioPlayer *player1 = new WAVPlayer(); 69 | AudioPlayer *player2 = new MP3Player(); 70 | AudioPlayer *player3 = new OGGPlayer(); 71 | 72 | player1->play(); 73 | player2->play(); 74 | player3->play(); 75 | 76 | delete player1; 77 | delete player2; 78 | delete player3; 79 | 80 | D2X_WAIT 81 | 82 | return 0; 83 | } -------------------------------------------------------------------------------- /dslings/cpp11/10-delegating-constructors-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/10-delegating-constructors-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 10 - delegating constructors | 委托构造函数 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解委托构造函数的基本使用 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/initializer_list.html#Delegating_constructor 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker delegating-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | static int construction_counter { 0 }; 24 | 25 | class Account { 26 | std::string id; 27 | std::string name; 28 | std::string coin; 29 | public: 30 | 31 | Account(std::string id_) { 32 | id = id_; 33 | name = "momo"; 34 | coin = "0元"; 35 | 36 | D2X_DONT_DELETE_THIS(construction_counter++); 37 | } 38 | 39 | Account(std::string id_, std::string name_) { 40 | id = id_; 41 | name = name_; 42 | coin = "0元"; 43 | 44 | D2X_DONT_DELETE_THIS(construction_counter++); 45 | } 46 | 47 | Account(std::string id_, std::string name_, int coin_) { 48 | id = id_; 49 | name = name_; 50 | coin = std::to_string(coin_) + "元"; 51 | 52 | D2X_DONT_DELETE_THIS(construction_counter++); 53 | } 54 | 55 | std::string to_string() const { 56 | return "Account { id: " + id + ", name: " + name + ", coin: " + coin + " }"; 57 | } 58 | }; 59 | 60 | int main() { // 不要修改main函数中的代码 61 | 62 | Account a1 { "1111" }; 63 | d2x_assert_eq(construction_counter, 3); 64 | std::cout << a1.to_string() << std::endl; 65 | 66 | Account a2 { "2222", "wukong" }; 67 | d2x_assert_eq(construction_counter, 5); 68 | std::cout << a2.to_string() << std::endl; 69 | 70 | Account a3 { "3333", "mcpp", 100 }; 71 | d2x_assert_eq(construction_counter, 6); 72 | std::cout << a3.to_string() << std::endl; 73 | 74 | Account gi { "0000", "GImpact", 648 }; 75 | std::cout << gi.to_string() << std::endl; 76 | 77 | d2x_assert( 78 | gi.to_string() == 79 | "Account { id: 0000, name: GImpact, coin: 648原石 }" 80 | ); 81 | 82 | D2X_WAIT 83 | 84 | return 0; 85 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/11-inherited-constructors-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-2.cpp 4 | // 5 | // Exercise: cpp11 | 11 - inherited constructors | Inherited Constructors in Generic Decorator Applications 6 | // 7 | // Tips: Based on compiler output and error messages, mimic the NoCopy class template to implement a NoMove class template 8 | // Make classes decorated by NoMove create objects that do not support move semantics 9 | // 10 | // Docs: 11 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 12 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 13 | // 14 | // Auto-Checker command: 15 | // 16 | // d2x checker inherited-constructors 17 | // 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | struct Point { 25 | double mX, mY; 26 | 27 | Point() : mX { 0 }, mY { 0 } { } 28 | Point(double x, double y) : mX { x }, mY { y } { } 29 | 30 | std::string to_string() const { 31 | return "{ " + std::to_string(mX) 32 | + ", " + std::to_string(mY) + " }"; 33 | } 34 | }; 35 | 36 | template 37 | class NoCopy : public T { 38 | public: 39 | using T::T; 40 | 41 | NoCopy(const NoCopy&) = delete; 42 | NoCopy& operator=(const NoCopy&) = delete; 43 | NoCopy(NoCopy&&) = default; 44 | NoCopy& operator=(NoCopy&&) = default; 45 | }; 46 | 47 | int main() { 48 | 49 | Point p1(1, 1); 50 | NoCopy p2(2, 2); 51 | 52 | std::cout << "p1: " << p1.to_string() << std::endl; 53 | std::cout << "p2: " << p2.to_string() << std::endl; 54 | 55 | auto p11 = p1; 56 | std::cout << "p11: " << p11.to_string() << std::endl; 57 | d2x_assert_eq(p1.mX, p11.mX); 58 | d2x_assert_eq(p1.mY, p11.mY); 59 | 60 | decltype(p2) p22 = p2; // by std::move? 61 | std::cout << "p22: " << p22.to_string() << std::endl; 62 | d2x_assert_eq(p2.mX, p22.mX); 63 | d2x_assert_eq(p2.mY, p22.mY); 64 | 65 | NoMove p3(3, 3); 66 | std::cout << "p3: " << p3.to_string() << std::endl; 67 | 68 | NoMove p33(0, 0); 69 | p33 = std::move(p3); // by copy? 70 | std::cout << "p33: " << p33.to_string() << std::endl; 71 | d2x_assert_eq(p3.mX, p33.mX); 72 | d2x_assert_eq(p3.mY, p33.mY); 73 | 74 | D2X_WAIT 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/10-delegating-constructors-0.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/10-delegating-constructors-0.cpp 4 | // 5 | // Exercise: cpp11 | 10 - delegating constructors | Delegating Constructors 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand basic usage of delegating constructors 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/initializer_list.html#Delegating_constructor 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker delegating-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | static int construction_counter { 0 }; 24 | 25 | class Account { 26 | std::string id; 27 | std::string name; 28 | std::string coin; 29 | public: 30 | 31 | Account(std::string id_) { 32 | id = id_; 33 | name = "momo"; 34 | coin = "0元"; 35 | 36 | D2X_DONT_DELETE_THIS(construction_counter++); 37 | } 38 | 39 | Account(std::string id_, std::string name_) { 40 | id = id_; 41 | name = name_; 42 | coin = "0元"; 43 | 44 | D2X_DONT_DELETE_THIS(construction_counter++); 45 | } 46 | 47 | Account(std::string id_, std::string name_, int coin_) { 48 | id = id_; 49 | name = name_; 50 | coin = std::to_string(coin_) + "元"; 51 | 52 | D2X_DONT_DELETE_THIS(construction_counter++); 53 | } 54 | 55 | std::string to_string() const { 56 | return "Account { id: " + id + ", name: " + name + ", coin: " + coin + " }"; 57 | } 58 | }; 59 | 60 | int main() { // Do not modify the code in the main function 61 | 62 | Account a1 { "1111" }; 63 | d2x_assert_eq(construction_counter, 3); 64 | std::cout << a1.to_string() << std::endl; 65 | 66 | Account a2 { "2222", "wukong" }; 67 | d2x_assert_eq(construction_counter, 5); 68 | std::cout << a2.to_string() << std::endl; 69 | 70 | Account a3 { "3333", "mcpp", 100 }; 71 | d2x_assert_eq(construction_counter, 6); 72 | std::cout << a3.to_string() << std::endl; 73 | 74 | Account gi { "0000", "GImpact", 648 }; 75 | std::cout << gi.to_string() << std::endl; 76 | 77 | d2x_assert( 78 | gi.to_string() == 79 | "Account { id: 0000, name: GImpact, coin: 648原石 }" 80 | ); 81 | 82 | D2X_WAIT 83 | 84 | return 0; 85 | } -------------------------------------------------------------------------------- /dslings/cpp11/05-move-semantics-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-2.cpp 4 | // 5 | // Exercise/练习: cpp11 | 05 - move semantics | 移动的是资源而不是对象 6 | // 7 | // Tips/提示: 观察编译器输出, 使用移动语义并观察对比对象和资源的移动 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker move-semantics-2 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Buffer { 22 | int *data; 23 | Buffer() : data { new int[2] {0, 1} } { 24 | std::cout << "Buffer():" << data << std::endl; 25 | } 26 | Buffer(const Buffer &other) { 27 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 28 | data = new int[2]; 29 | data[0] = other.data[0]; 30 | data[1] = other.data[1]; 31 | } 32 | Buffer(Buffer&& other) : data { other.data } { 33 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 34 | other.data = nullptr; // 让原对象的指针失效 35 | } 36 | Buffer & operator=(const Buffer &other) { 37 | std::cout << "Buffer& operator=(const Buffer&):" << data << std::endl; 38 | if (this != &other) { 39 | delete[] data; // 释放旧资源 40 | data = new int[2]; 41 | data[0] = other.data[0]; 42 | data[1] = other.data[1]; 43 | } 44 | return *this; 45 | } 46 | Buffer & operator=(Buffer&& other) { 47 | std::cout << "Buffer& operator=(Buffer&&):" << data << std::endl; 48 | if (this != &other) { 49 | delete[] data; // 释放旧资源 - 步骤1 50 | data = other.data; // 转移资源 - 步骤2 51 | other.data = nullptr; // 让原对象的指针失效 - 步骤3 52 | } 53 | return *this; 54 | } 55 | ~Buffer() { 56 | if (data) { 57 | std::cout << "~Buffer():" << data << std::endl; 58 | delete[] data; 59 | } 60 | } 61 | const int * data_ptr() const { 62 | return data; 63 | } 64 | }; 65 | 66 | int main() { // 移动语义 - 移动的是资源而不是对象演示 67 | 68 | { 69 | Buffer b1; // 调用默认构造函数 70 | 71 | auto old_b1_data_ptr = b1.data_ptr(); 72 | 73 | Buffer b2 = b1; // std::move(b1); 74 | 75 | d2x_assert(&b1 != &b2); // b1 和 b2 是不同的对象 76 | d2x_assert(old_b1_data_ptr == b2.data_ptr()); 77 | d2x_assert(b1.data_ptr() == nullptr); // b1 的资源被移动了 78 | 79 | } 80 | 81 | D2X_WAIT 82 | 83 | return 0; 84 | } -------------------------------------------------------------------------------- /dslings/cpp11/10-delegating-constructors-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/10-delegating-constructors-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 10 - delegating constructors | 委托构造函数注意事项 6 | // 7 | // Tips/提示: 根据编译器的输出, 修复编译器报错, 了解委托构造函数的注意事项 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/initializer_list.html#Delegating_constructor 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker delegating-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct Object { // 不要修改这个类的代码 24 | static int construction_counter; 25 | std::string name; 26 | Object() { 27 | construction_counter++; 28 | } 29 | 30 | Object(std::string name_) : name { name_ } { 31 | construction_counter++; 32 | } 33 | }; 34 | 35 | class Account { 36 | std::string id; 37 | std::string name; 38 | std::string coin; 39 | Object obj; 40 | public: 41 | 42 | Account(std::string id_) 43 | : Account(id_, "momo"), coin { "100元" } 44 | { 45 | 46 | } 47 | 48 | Account(std::string id_, std::string name_) { 49 | Account(id_, name_, 0); 50 | } 51 | 52 | Account(std::string id_, std::string name_, int coin_) { 53 | id = id_; 54 | name = name_; 55 | coin = std::to_string(coin_) + "元"; 56 | obj = Object(name_); 57 | } 58 | 59 | std::string get_id() const { 60 | return id; 61 | } 62 | 63 | std::string get_object_name() const { 64 | return obj.name; 65 | } 66 | 67 | std::string to_string() const { 68 | return "Account { id: " + id + ", name: " + name + ", coin: " + coin 69 | + ", Object { name: " + obj.name 70 | + ", construction_counter: " + std::to_string(Object::construction_counter) + " } }"; 71 | } 72 | }; 73 | 74 | int Object::construction_counter { 0 }; 75 | 76 | int main() { // 不要修改main函数中的代码 77 | 78 | Account a1 { "1111", "hello" }; 79 | std::cout << a1.to_string() << std::endl; 80 | d2x_assert(a1.get_id() == "1111"); 81 | 82 | Object::construction_counter = 0; 83 | Account a2 { "2222", "d2learn", 100 }; 84 | std::cout << a2.to_string() << std::endl; 85 | 86 | d2x_assert(a2.get_object_name() == "d2learn"); 87 | d2x_assert_eq(Object::construction_counter, 1); 88 | 89 | D2X_WAIT 90 | 91 | return 0; 92 | } -------------------------------------------------------------------------------- /book/src/changelog.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./changelog.html 7 | [English]: ../en/changelog.html 8 | 9 | # mcpp-standard更新日志 10 | 11 | ## 2025/11 12 | 13 | --- 14 | 15 | **C++11 - 13 - long long - 64位整数类型** 16 | 17 | - `Book`: [zh](https://sunrisepeak.github.io/mcpp-standard/cpp11/13-long-long.html) / [en](https://sunrisepeak.github.io/mcpp-standard/en/cpp11/13-long-long.html) - 2025/11/03 18 | - `Code`: [zh](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/13-long-long-0.cpp) / [en](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/en/cpp11/13-long-long-0.cpp) - 2025/11/03 19 | 20 | **C++11 - 12 - nullptr - 指针字面量** 21 | 22 | - `Book`: [zh](https://sunrisepeak.github.io/mcpp-standard/cpp11/12-nullptr.html) / [en](https://sunrisepeak.github.io/mcpp-standard/en/cpp11/12-nullptr.html) - 2025/11/02 23 | - `Code`: [zh](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-0.cpp) / [en](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/en/cpp11/12-nullptr-0.cpp) - 2025/11/02 24 | 25 | ## 2025/09 26 | 27 | --- 28 | **C++11 - 11 - 继承构造造函数** 29 | 30 | - **video:** [Bili](https://www.bilibili.com/video/BV1bspBzFEEC) / [Youtube](https://youtu.be/p7vbY8XUKnY?si=GZUn9GSW68aU94A6) / [Code](https://github.com/Sunrisepeak/mcpp-standard/blob/main/videos/cpp11/11-inherited-constructors.py) 31 | 32 | ## 2025/08 33 | 34 | --- 35 | **C++11 - 11 - 继承构造造函数** 36 | 37 | - **[code-0](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-0.cpp) / [code-1](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-1.cpp) / [code-2](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-2.cpp)** - 2025/08/29 38 | - **[book](https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html)** - 2025/08/28 39 | - **video** - todo 40 | 41 | --- 42 | **C++11 - 10 - 委托构造函数** 43 | 44 | - **[video](https://www.bilibili.com/video/BV1zft3zSEER) / [anim-code](https://github.com/Sunrisepeak/mcpp-standard/blob/main/videos/cpp11/10-delegating-constructors.py)** - 2025/08/04 45 | - **[code-0](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/10-delegating-constructors-0.cpp) / [code-1](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/10-delegating-constructors-1.cpp)** - 2025/08/02 46 | - **[book](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md)** - 2025/08/01 47 | 48 | **练习检测命令** 49 | 50 | ```bash 51 | d2x checker delegating-constructors 52 | ``` 53 | -------------------------------------------------------------------------------- /dslings/en/cpp11/10-delegating-constructors-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/10-delegating-constructors-1.cpp 4 | // 5 | // Exercise: cpp11 | 10 - delegating constructors | Delegating Constructors Precautions 6 | // 7 | // Tips: Fix compiler errors based on compiler output, understand precautions for delegating constructors 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/initializer_list.html#Delegating_constructor 11 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker delegating-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | struct Object { // Do not modify the code of this class 24 | static int construction_counter; 25 | std::string name; 26 | Object() { 27 | construction_counter++; 28 | } 29 | 30 | Object(std::string name_) : name { name_ } { 31 | construction_counter++; 32 | } 33 | }; 34 | 35 | class Account { 36 | std::string id; 37 | std::string name; 38 | std::string coin; 39 | Object obj; 40 | public: 41 | 42 | Account(std::string id_) 43 | : Account(id_, "momo"), coin { "100元" } 44 | { 45 | 46 | } 47 | 48 | Account(std::string id_, std::string name_) { 49 | Account(id_, name_, 0); 50 | } 51 | 52 | Account(std::string id_, std::string name_, int coin_) { 53 | id = id_; 54 | name = name_; 55 | coin = std::to_string(coin_) + "元"; 56 | obj = Object(name_); 57 | } 58 | 59 | std::string get_id() const { 60 | return id; 61 | } 62 | 63 | std::string get_object_name() const { 64 | return obj.name; 65 | } 66 | 67 | std::string to_string() const { 68 | return "Account { id: " + id + ", name: " + name + ", coin: " + coin 69 | + ", Object { name: " + obj.name 70 | + ", construction_counter: " + std::to_string(Object::construction_counter) + " } }"; 71 | } 72 | }; 73 | 74 | int Object::construction_counter { 0 }; 75 | 76 | int main() { // Do not modify the code in the main function 77 | 78 | Account a1 { "1111", "hello" }; 79 | std::cout << a1.to_string() << std::endl; 80 | d2x_assert(a1.get_id() == "1111"); 81 | 82 | Object::construction_counter = 0; 83 | Account a2 { "2222", "d2learn", 100 }; 84 | std::cout << a2.to_string() << std::endl; 85 | 86 | d2x_assert(a2.get_object_name() == "d2learn"); 87 | d2x_assert_eq(Object::construction_counter, 1); 88 | 89 | D2X_WAIT 90 | 91 | return 0; 92 | } -------------------------------------------------------------------------------- /book/en/src/changelog.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ../changelog.html 7 | [English]: ./changelog.html 8 | 9 | # mcpp-standard Changelog 10 | 11 | ## 2025/11 12 | 13 | --- 14 | 15 | **C++11 - 13 - long long - 64-bit Integer Type** 16 | 17 | - `Book`: [zh](https://sunrisepeak.github.io/mcpp-standard/cpp11/13-long-long.html) / [en](https://sunrisepeak.github.io/mcpp-standard/en/cpp11/13-long-long.html) - 2025/11/03 18 | - `Code`: [zh](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/13-long-long-0.cpp) / [en](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/en/cpp11/13-long-long-0.cpp) - 2025/11/03 19 | 20 | **C++11 - 12 - nullptr - Pointer Literal** 21 | 22 | - `Book`: [zh](https://sunrisepeak.github.io/mcpp-standard/cpp11/12-nullptr.html) / [en](https://sunrisepeak.github.io/mcpp-standard/en/cpp11/12-nullptr.html) - 2025/11/02 23 | - `Code`: [zh](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-0.cpp) / [en](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/en/cpp11/12-nullptr-0.cpp) - 2025/11/02 24 | 25 | ## 2025/09 26 | 27 | --- 28 | **C++11 - 11 - Inherited Constructors** 29 | 30 | - **video:** [Bili](https://www.bilibili.com/video/BV1bspBzFEEC) / [Youtube](https://youtu.be/p7vbY8XUKnY?si=GZUn9GSW68aU94A6) / [Code](https://github.com/Sunrisepeak/mcpp-standard/blob/main/videos/cpp11/11-inherited-constructors.py) 31 | 32 | ## 2025/08 33 | 34 | --- 35 | **C++11 - 11 - Inherited Constructors** 36 | 37 | - **[code-0](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-0.cpp) / [code-1](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-1.cpp) / [code-2](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-2.cpp)** - 2025/08/29 38 | - **[book](https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html)** - 2025/08/28 39 | - **video** - todo 40 | 41 | --- 42 | **C++11 - 10 - Delegating Constructors** 43 | 44 | - **[video](https://www.bilibili.com/video/BV1zft3zSEER) / [anim-code](https://github.com/Sunrisepeak/mcpp-standard/blob/main/videos/cpp11/10-delegating-constructors.py)** - 2025/08/04 45 | - **[code-0](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/10-delegating-constructors-0.cpp) / [code-1](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/10-delegating-constructors-1.cpp)** - 2025/08/02 46 | - **[book](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/10-delegating-constructors.md)** - 2025/08/01 47 | 48 | **Practice Detection Command** 49 | 50 | ```bash 51 | d2x checker delegating-constructors 52 | ``` 53 | -------------------------------------------------------------------------------- /dslings/en/cpp11/05-move-semantics-2.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-2.cpp 4 | // 5 | // Exercise: cpp11 | 05 - move semantics | Moving resources not objects 6 | // 7 | // Tips: Observe compiler output, use move semantics and observe the movement of objects vs resources 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker move-semantics-2 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | struct Buffer { 22 | int *data; 23 | Buffer() : data { new int[2] {0, 1} } { 24 | std::cout << "Buffer():" << data << std::endl; 25 | } 26 | Buffer(const Buffer &other) { 27 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 28 | data = new int[2]; 29 | data[0] = other.data[0]; 30 | data[1] = other.data[1]; 31 | } 32 | Buffer(Buffer&& other) : data { other.data } { 33 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 34 | other.data = nullptr; // Invalidate the pointer of the original object 35 | } 36 | Buffer & operator=(const Buffer &other) { 37 | std::cout << "Buffer& operator=(const Buffer&):" << data << std::endl; 38 | if (this != &other) { 39 | delete[] data; // Release old resources 40 | data = new int[2]; 41 | data[0] = other.data[0]; 42 | data[1] = other.data[1]; 43 | } 44 | return *this; 45 | } 46 | Buffer & operator=(Buffer&& other) { 47 | std::cout << "Buffer& operator=(Buffer&&):" << data << std::endl; 48 | if (this != &other) { 49 | delete[] data; // Release old resources - Step 1 50 | data = other.data; // Transfer resources - Step 2 51 | other.data = nullptr; // Invalidate the pointer of the original object - Step 3 52 | } 53 | return *this; 54 | } 55 | ~Buffer() { 56 | if (data) { 57 | std::cout << "~Buffer():" << data << std::endl; 58 | delete[] data; 59 | } 60 | } 61 | const int * data_ptr() const { 62 | return data; 63 | } 64 | }; 65 | 66 | int main() { // Move semantics - Demonstrating moving resources not objects 67 | 68 | { 69 | Buffer b1; // Call default constructor 70 | 71 | auto old_b1_data_ptr = b1.data_ptr(); 72 | 73 | Buffer b2 = b1; // std::move(b1); 74 | 75 | d2x_assert(&b1 != &b2); // b1 and b2 are different objects 76 | d2x_assert(old_b1_data_ptr == b2.data_ptr()); 77 | d2x_assert(b1.data_ptr() == nullptr); // b1's resources have been moved 78 | 79 | } 80 | 81 | D2X_WAIT 82 | 83 | return 0; 84 | } -------------------------------------------------------------------------------- /dslings/cpp11/11-inherited-constructors-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-1.cpp 4 | // 5 | // Exercise/练习: cpp11 | 11 - inherited constructors | 继承构造函数于功能扩展 6 | // 7 | // Tips/提示: 根据编译器的输出和报错提示, 实现符合要求的Student辅助测试类 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 11 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 12 | // 13 | // Auto-Checker/自动检测命令: 14 | // 15 | // d2x checker inherited-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class Student { // 不要直接修改 Student 类中的代码 24 | protected: 25 | //... 26 | int score; 27 | public: 28 | std::string id; 29 | std::string name; 30 | int age; 31 | 32 | Student() : id("001"), name("张三"), age(18), score(0) { 33 | std::cout << "Student::Student()" << std::endl; 34 | } 35 | 36 | Student(std::string id, std::string name, int age = 18) 37 | : id(id), name(name), age(age), score(0) { 38 | std::cout << "Student::Student(string, string, int)" << std::endl; 39 | } 40 | 41 | void set_score(int s) { score = s; } 42 | void set_age(int a) { age = a; } 43 | }; 44 | 45 | class StudentTest : public Student { 46 | public: 47 | 48 | D2X_YOUR_ANSWER // 实现Student的辅助测试类 49 | 50 | std::string to_string() const { 51 | return "{" + id + ", " + name + ", " + std::to_string(age) + ", " + std::to_string(score) + "}"; 52 | } 53 | }; 54 | 55 | // 测试要求: 56 | // score_valid: [0 ~ 100] 57 | // age_valid: (0 ~ 200] 58 | // to_string: {id, name, age, score} 59 | 60 | int main() { // 不要直接修改 main 函数中的代码 61 | 62 | { // 基础测试 63 | StudentTest studentTest; 64 | 65 | d2x_assert(studentTest.age_valid() == true); 66 | d2x_assert(studentTest.score_valid() == true); 67 | d2x_assert(studentTest.to_string() == "{001, 张三, 18, 0}"); 68 | } 69 | 70 | { // 边界测试 71 | StudentTest studentTest("002", "张三", 201); 72 | 73 | d2x_assert(studentTest.score_valid() == true); 74 | d2x_assert(studentTest.age_valid() == false); 75 | 76 | studentTest.set_score(101); 77 | studentTest.set_age(200); 78 | d2x_assert(studentTest.score_valid() == false); 79 | d2x_assert(studentTest.age_valid() == true); 80 | 81 | studentTest.set_score(0); 82 | studentTest.set_age(1); 83 | d2x_assert(studentTest.score_valid() == true); 84 | d2x_assert(studentTest.age_valid() == true); 85 | 86 | studentTest.set_score(-1); 87 | studentTest.set_age(0); 88 | d2x_assert(studentTest.score_valid() == false); 89 | d2x_assert(studentTest.age_valid() == false); 90 | 91 | } 92 | 93 | D2X_WAIT 94 | 95 | return 0; 96 | } -------------------------------------------------------------------------------- /dslings/cpp11/05-move-semantics-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-0.cpp 4 | // 5 | // Exercise/练习: cpp11 | 05 - move semantics | 移动赋值与触发时机 6 | // 7 | // Tips/提示: 观察编译器输出, 在不改变buff传递的逻辑, 使得只做一次资源的分配和释放 8 | // 9 | // Docs/文档: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker/自动检测命令: 13 | // 14 | // d2x checker move-semantics 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | 22 | static int move_assignment_counter = 0; 23 | 24 | struct Buffer { 25 | int *data; 26 | Buffer() : data { new int[2] {0, 1} } { 27 | std::cout << "Buffer():" << data << std::endl; 28 | } 29 | Buffer(const Buffer &other) { 30 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 31 | data = new int[2]; 32 | data[0] = other.data[0]; 33 | data[1] = other.data[1]; 34 | } 35 | Buffer(Buffer&& other) : data { other.data } { 36 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 37 | other.data = nullptr; // 让原对象的指针失效 38 | } 39 | Buffer & operator=(const Buffer &other) { 40 | std::cout << "Buffer& operator=(const Buffer&):" << data << std::endl; 41 | if (this != &other) { 42 | delete[] data; // 释放旧资源 43 | data = new int[2]; 44 | data[0] = other.data[0]; 45 | data[1] = other.data[1]; 46 | } 47 | return *this; 48 | } 49 | Buffer & operator=(Buffer&& other) { 50 | move_assignment_counter++; 51 | std::cout << "Buffer& operator=(Buffer&&):" << data << std::endl; 52 | if (this != &other) { 53 | delete[] data; // 释放旧资源 54 | data = other.data; // 转移资源 55 | other.data = nullptr; // 让原对象的指针失效 56 | } 57 | return *this; 58 | } 59 | ~Buffer() { 60 | if (data) { 61 | std::cout << "~Buffer():" << data << std::endl; 62 | delete[] data; 63 | } 64 | } 65 | const int * data_ptr() const { 66 | std::cout << "data[0] = " << data[0] << ", data[1] = " << data[1] << std::endl; 67 | return data; 68 | } 69 | }; 70 | 71 | Buffer process(Buffer buff) { 72 | std::cout << "process(): " << buff.data << std::endl; 73 | return buff; 74 | } 75 | 76 | int main() { // 无编译器优化 77 | 78 | { 79 | Buffer buff1; 80 | 81 | buff1 = Buffer(); // 情况1: 临时对象赋值 82 | 83 | d2x_assert_eq(move_assignment_counter, 1); 84 | 85 | Buffer buff2; 86 | 87 | buff2 = process(buff1); // 情况2: 中间对象赋值 88 | 89 | d2x_assert_eq(move_assignment_counter, 2); 90 | 91 | buff2 = buff1; // 情况3: 显示移动赋值 92 | 93 | d2x_assert_eq(move_assignment_counter, 3); 94 | 95 | } 96 | 97 | D2X_WAIT 98 | 99 | return 0; 100 | } -------------------------------------------------------------------------------- /dslings/en/cpp11/11-inherited-constructors-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/11-inherited-constructors-1.cpp 4 | // 5 | // Exercise: cpp11 | 11 - inherited constructors | Inherited Constructors for Function Extension 6 | // 7 | // Tips: Based on compiler output and error prompts, implement the required Student helper test class 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/using_declaration.html#Inheriting_constructors 11 | // - https://sunrisepeak.github.io/mcpp-standard/cpp11/11-inherited-constructors.html 12 | // 13 | // Auto-Checker command: 14 | // 15 | // d2x checker inherited-constructors 16 | // 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | class Student { // Do not directly modify the code in the Student class 24 | protected: 25 | //... 26 | int score; 27 | public: 28 | std::string id; 29 | std::string name; 30 | int age; 31 | 32 | Student() : id("001"), name("张三"), age(18), score(0) { 33 | std::cout << "Student::Student()" << std::endl; 34 | } 35 | 36 | Student(std::string id, std::string name, int age = 18) 37 | : id(id), name(name), age(age), score(0) { 38 | std::cout << "Student::Student(string, string, int)" << std::endl; 39 | } 40 | 41 | void set_score(int s) { score = s; } 42 | void set_age(int a) { age = a; } 43 | }; 44 | 45 | class StudentTest : public Student { 46 | public: 47 | 48 | D2X_YOUR_ANSWER // Implement Student's helper test class 49 | 50 | std::string to_string() const { 51 | return "{" + id + ", " + name + ", " + std::to_string(age) + ", " + std::to_string(score) + "}"; 52 | } 53 | }; 54 | 55 | // Test requirements: 56 | // score_valid: [0 ~ 100] 57 | // age_valid: (0 ~ 200] 58 | // to_string: {id, name, age, score} 59 | 60 | int main() { // Do not directly modify the code in the main function 61 | 62 | { // Basic test 63 | StudentTest studentTest; 64 | 65 | d2x_assert(studentTest.age_valid() == true); 66 | d2x_assert(studentTest.score_valid() == true); 67 | d2x_assert(studentTest.to_string() == "{001, 张三, 18, 0}"); 68 | } 69 | 70 | { // Boundary test 71 | StudentTest studentTest("002", "张三", 201); 72 | 73 | d2x_assert(studentTest.score_valid() == true); 74 | d2x_assert(studentTest.age_valid() == false); 75 | 76 | studentTest.set_score(101); 77 | studentTest.set_age(200); 78 | d2x_assert(studentTest.score_valid() == false); 79 | d2x_assert(studentTest.age_valid() == true); 80 | 81 | studentTest.set_score(0); 82 | studentTest.set_age(1); 83 | d2x_assert(studentTest.score_valid() == true); 84 | d2x_assert(studentTest.age_valid() == true); 85 | 86 | studentTest.set_score(-1); 87 | studentTest.set_age(0); 88 | d2x_assert(studentTest.score_valid() == false); 89 | d2x_assert(studentTest.age_valid() == false); 90 | 91 | } 92 | 93 | D2X_WAIT 94 | 95 | return 0; 96 | } -------------------------------------------------------------------------------- /book/src/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 👉 📚 [中文] | [English] | [Github] 4 |
5 | 6 |
7 | 8 | 9 | 动手学 | 现代CPP核心语言特性 - "强调动手实践的C++教程项目" 10 | 11 | [📚Book] + [🎥Video] + [⌨️Code] + [👥X] 12 |
13 | 14 | [中文]: ./ 15 | [Github]: https://github.com/Sunrisepeak/mcpp-standard 16 | [English]: ./en 17 | 18 | [📚Book]: https://sunrisepeak.github.io/mcpp-standard 19 | [🎥Video]: https://www.bilibili.com/video/BV182MtzPEiX 20 | [⌨️Code]: https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings 21 | [👥X]: https://forum.d2learn.org/category/20 22 | 23 | ## 目标 24 | 25 | - **`[掌握]`** - **现代C++核心的语言特性**及使用场景 26 | - **`[掌握]`** - 通过编译器报错信息**定位问题的能力** 27 | - **`[熟悉]`** - 通过文档和[cppreference](https://cppreference.com)解决C++中不熟悉问题的能力 28 | - **`[了解]`** - 如何参与技术社区 - 开源项目的使用、提问题、参与讨论或贡献 29 | 30 | ## 快速开始 31 | 32 | ### 在线代码练习 33 | 34 | > [**点击下面按钮**](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 即可在云端自动完成配置, 并进入练习代码检测模式 35 | 36 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 37 | 38 | ### 搭建本地练习环境 39 | 40 | > 尝试 `Code -> Book -> Video -> X -> Code` 41 | 42 |
43 | 点击查看xlings安装命令 44 | 45 | --- 46 | 47 | #### Linux/MacOS 48 | 49 | ```bash 50 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 51 | ``` 52 | 53 | #### Windows - PowerShell 54 | 55 | ```bash 56 | irm https://d2learn.org/xlings-install.ps1.txt | iex 57 | ``` 58 | 59 | > 注: xlings工具 -> [详情](https://xlings.d2learn.org) 60 | 61 | --- 62 | 63 |
64 | 65 | ```bash 66 | xlings install d2x:mcpp-standard 67 | cd mcpp-standard 68 | d2x checker 69 | ``` 70 | 71 | **👉 [更多细节...](https://sunrisepeak.github.io/mcpp-standard/base/chapter_1.html)** 72 | 73 | ## 社区 74 | 75 | - **即时交流:** 167535744、1067245099 76 | - [**论坛版块:**](https://forum.d2learn.org/category/20) 问题反馈、练习代码、技术交流和讨论 77 | - **社区活动:** [📣 MSCP - mcpp项目学习与贡献者培养计划](https://moga.d2learn.org/activity/mscp/intro.html) 78 | 79 | > **注:** 复杂性问题(技术、环境搭建等问题)推荐在论坛发帖, 并详细描述问题细节, 能更有效于问题的解决和复用 80 | 81 | ## 参与贡献 82 | 83 | - **参与社区交流:** 反馈问题、参与社区问题讨论、帮助社区新用户解决问题 84 | - **参与项目维护和开发:** 参与社区中问题处理、修复Bug、多语言支持、[加入MSCP活动小组](https://moga.d2learn.org/activity/mscp/docs/join-group.html)、开发&优化新功能/模块 85 | 86 | **📑开源协议与贡献许可(License & CLA)** 87 | 88 | - 本项目欢迎自由使用与分发!你可以在 [Apache License 2.0](LICENSE-CODE) 和 [CC-BY-NC-SA 4.0](LICENSE-BOOK) 协议下**免费**使用、修改和分享本项目的代码与文档内容 89 | - 如希望参与贡献代码或文档,请先阅读[贡献者许可协议(CLA)](CLA.md) 90 | 91 | **👥贡献者** 92 | 93 | 94 | 95 | 96 | 97 | Featured|HelloGitHub 98 | -------------------------------------------------------------------------------- /dslings/en/hello-mcpp.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/hello-mcpp.cpp 4 | // 5 | // Exercise: Automated Code Practice Usage Tutorial 6 | // 7 | // Tips: 8 | // This project is an automated code practice project built using the xlings tool. 9 | // By executing `xlings checker` in the project root directory, you enter the 10 | // "compiler-driven development mode" for automatic code practice detection. 11 | // You need to modify errors in the code based on console error messages and prompts. 12 | // After fixing all compilation errors and runtime checkpoints, you can delete or 13 | // comment out the D2X_WAIT macro in the code to automatically proceed to the next exercise. 14 | // 15 | // - D2X_WAIT: This macro is used to isolate different exercises. You can delete or 16 | // comment out this macro to proceed to the next exercise. 17 | // - d2x_assert_eq: This macro is used for runtime checkpoints. You need to fix 18 | // errors in the code so that all checkpoints pass. 19 | // - D2X_YOUR_ANSWER: This macro indicates code that needs to be modified, generally 20 | // used for code completion (replace this macro with correct code) 21 | // 22 | // Docs: 23 | // - https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/chapter_1.md 24 | // - book/src/chapter_1.md 25 | // 26 | // Auto-Checker command: 27 | // 28 | // d2x checker hello-mcpp 29 | // 30 | 31 | #include 32 | 33 | // You can observe "real-time" changes in the console when modifying code 34 | 35 | int main() { 36 | 37 | std::cout << "hello, mcpp!" << std:endl; // 0. Fix this compilation error 38 | 39 | int a = 1.1; // 1. Fix this runtime error, change int to double to pass the check 40 | 41 | d2x_assert_eq(a, 1.1); // 2. Runtime checkpoint, need to fix code to pass all checkpoints (cannot directly delete checkpoint code) 42 | 43 | D2X_YOUR_ANSWER b = a; // 3. Fix this compilation error, give b an appropriate type 44 | 45 | d2x_assert_eq(b, 1); // 4. Runtime checkpoint 2 46 | 47 | D2X_WAIT // 5. Delete or comment out this macro to proceed to the next exercise (project formal code practice) 48 | 49 | return 0; 50 | } 51 | 52 | //// --- More detailed introduction | | | 53 | // V V V 54 | /* 55 | 56 | # [[ Console Output Interpretation ]] 57 | 58 | 🌏Progress: [>----------] 0/10 -->> Shows current exercise progress 59 | 60 | [Target: 00-0-hello-mcpp] - normal -->> Current exercise name 61 | 62 | ❌ Error: Compilation/Running failed for dslings/hello-mcpp.cpp -->> Shows detection status 63 | 64 | The code exist some error! 65 | 66 | ---------C-Output--------- - Compiler output information 67 | [HONLY LOGW]: main: dslings/hello-mcpp.cpp:24 - ❌ | a == 1.1 (1 == 1.100000) -->> Error prompt and location (line 24) 68 | [HONLY LOGW]: main: dslings/hello-mcpp.cpp:26 - 🥳 Delete the D2X_WAIT to continue... 69 | 70 | 71 | AI-Tips-Config: https://d2learn.org/docs/xlings -->> AI tips (requires configuring large model key, optional) 72 | 73 | ---------E-Files--------- 74 | dslings/hello-mcpp.cpp -->> Current file being checked 75 | ------------------------- 76 | 77 | Homepage: https://github.com/d2learn/xlings 78 | 79 | */ -------------------------------------------------------------------------------- /dslings/en/cpp11/05-move-semantics-1.cpp: -------------------------------------------------------------------------------- 1 | // mcpp-standard: https://github.com/Sunrisepeak/mcpp-standard 2 | // license: Apache-2.0 3 | // file: dslings/cpp11/05-move-semantics-1.cpp 4 | // 5 | // Exercise: cpp11 | 05 - move semantics | Move Assignment and Trigger Timing 6 | // 7 | // Tips: Observe compiler output, without changing the buff passing logic, ensure only one resource allocation and deallocation 8 | // 9 | // Docs: 10 | // - https://en.cppreference.com/w/cpp/language/move_constructor 11 | // 12 | // Auto-Checker command: 13 | // 14 | // d2x checker move-semantics 15 | // 16 | 17 | #include 18 | 19 | #include 20 | 21 | 22 | static int move_assignment_counter = 0; 23 | 24 | struct Buffer { 25 | int *data; 26 | Buffer() : data { new int[2] {0, 1} } { 27 | std::cout << "Buffer():" << data << std::endl; 28 | } 29 | Buffer(const Buffer &other) { 30 | std::cout << "Buffer(const Buffer&):" << data << std::endl; 31 | data = new int[2]; 32 | data[0] = other.data[0]; 33 | data[1] = other.data[1]; 34 | } 35 | Buffer(Buffer&& other) : data { other.data } { 36 | std::cout << "Buffer(Buffer&&):" << data << std::endl; 37 | other.data = nullptr; // Invalidate the pointer of the original object 38 | } 39 | Buffer & operator=(const Buffer &other) { 40 | std::cout << "Buffer& operator=(const Buffer&):" << data << std::endl; 41 | if (this != &other) { 42 | delete[] data; // Release old resources 43 | data = new int[2]; 44 | data[0] = other.data[0]; 45 | data[1] = other.data[1]; 46 | } 47 | return *this; 48 | } 49 | Buffer & operator=(Buffer&& other) { 50 | move_assignment_counter++; 51 | std::cout << "Buffer& operator=(Buffer&&):" << data << std::endl; 52 | if (this != &other) { 53 | delete[] data; // Release old resources 54 | data = other.data; // Transfer resources 55 | other.data = nullptr; // Invalidate the pointer of the original object 56 | } 57 | return *this; 58 | } 59 | ~Buffer() { 60 | if (data) { 61 | std::cout << "~Buffer():" << data << std::endl; 62 | delete[] data; 63 | } 64 | } 65 | const int * data_ptr() const { 66 | std::cout << "data[0] = " << data[0] << ", data[1] = " << data[1] << std::endl; 67 | return data; 68 | } 69 | }; 70 | 71 | Buffer process(Buffer buff) { 72 | std::cout << "process(): " << buff.data << std::endl; 73 | return buff; 74 | } 75 | 76 | int main() { // No compiler optimization 77 | 78 | { 79 | Buffer buff1; 80 | 81 | buff1 = Buffer(); // Case 1: Temporary object assignment 82 | 83 | d2x_assert_eq(move_assignment_counter, 1); 84 | 85 | Buffer buff2; 86 | 87 | buff2 = process(buff1); // Case 2: Intermediate object assignment 88 | 89 | d2x_assert_eq(move_assignment_counter, 2); 90 | 91 | buff2 = buff1; // Case 3: Explicit move assignment 92 | 93 | d2x_assert_eq(move_assignment_counter, 3); 94 | 95 | } 96 | 97 | D2X_WAIT 98 | 99 | return 0; 100 | } -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | [中文] | [繁體中文] | [English] | [Todo] 4 |
5 | 6 |
7 | 8 | 9 | 动手学 | 现代CPP核心语言特性 - "强调动手实践的C++教程项目" 10 | 11 | [📚Book] + [🎥Video] + [⌨️Code] + [👥X] 12 |
13 | 14 | [中文]: README.zh.md 15 | [繁體中文]: README.zh.hant.md 16 | [English]: README.md 17 | [Todo]: README.md 18 | 19 | [📚Book]: https://sunrisepeak.github.io/mcpp-standard 20 | [🎥Video]: https://www.bilibili.com/video/BV182MtzPEiX 21 | [⌨️Code]: https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings 22 | [👥X]: https://forum.d2learn.org/category/20 23 | 24 | > [!CAUTION] 25 | > 该项目当前处于开发初期, 如果你发现任何问题, 欢迎创建issues反馈或直接提交PR进行修复 26 | 27 | ## 目标 28 | 29 | - **`[掌握]`** - **现代C++核心的语言特性**及使用场景 30 | - **`[掌握]`** - 通过编译器报错信息**定位问题的能力** 31 | - **`[熟悉]`** - 通过文档和[cppreference](https://cppreference.com)解决C++中不熟悉问题的能力 32 | - **`[了解]`** - 如何参与技术社区 - 开源项目的使用、提问题、参与讨论或贡献 33 | 34 | ## 快速开始 35 | 36 | ### 在线代码练习 37 | 38 | > [**点击下面按钮**](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 即可在云端自动完成配置, 并进入练习代码检测模式 39 | 40 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 41 | 42 | ### 搭建本地练习环境 43 | 44 | > 尝试 `Code -> Book -> Video -> X -> Code` 45 | 46 |
47 | 点击查看xlings安装命令 48 | 49 | --- 50 | 51 | #### Linux/MacOS 52 | 53 | ```bash 54 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 55 | ``` 56 | 57 | #### Windows - PowerShell 58 | 59 | ```bash 60 | irm https://d2learn.org/xlings-install.ps1.txt | iex 61 | ``` 62 | 63 | > 注: xlings工具 -> [详情](https://xlings.d2learn.org) 64 | 65 | --- 66 | 67 |
68 | 69 | ```bash 70 | xlings install d2x:mcpp-standard 71 | cd mcpp-standard 72 | d2x checker 73 | ``` 74 | 75 | **👉 [更多细节...](https://sunrisepeak.github.io/mcpp-standard/base/chapter_1.html)** 76 | 77 | ## 社区 78 | 79 | - **即时交流:** 167535744、1067245099 80 | - [**论坛版块:**](https://forum.d2learn.org/category/20) 问题反馈、练习代码、技术交流和讨论 81 | - **社区活动:** [📣 MSCP - mcpp项目学习与贡献者培养计划](https://moga.d2learn.org/activity/mscp/intro.html) 82 | 83 | > **注:** 复杂性问题(技术、环境搭建等问题)推荐在论坛发帖, 并详细描述问题细节, 能更有效于问题的解决和复用 84 | 85 | ## 参与贡献 86 | 87 | - **参与社区交流:** 反馈问题、参与社区问题讨论、帮助社区新用户解决问题 88 | - **参与项目维护和开发:** 参与社区中问题处理、修复Bug、多语言支持、[加入MSCP活动小组](https://moga.d2learn.org/activity/mscp/docs/join-group.html)、开发&优化新功能/模块 89 | 90 | **📑开源协议与贡献许可(License & CLA)** 91 | 92 | - 本项目欢迎自由使用与分发!你可以在 [Apache License 2.0](LICENSE-CODE) 和 [CC-BY-NC-SA 4.0](LICENSE-BOOK) 协议下**免费**使用、修改和分享本项目的代码与文档内容 93 | - 如希望参与贡献代码或文档,请先阅读[贡献者许可协议(CLA)](CLA.md) 94 | 95 | **👥贡献者** 96 | 97 | [![Star History Chart](https://api.star-history.com/svg?repos=Sunrisepeak/mcpp-standard&type=date&legend=top-left)](https://www.star-history.com/#Sunrisepeak/mcpp-standard&type=date&legend=top-left) 98 | 99 | 100 | 101 | 102 | 103 | Featured|HelloGitHub 104 | -------------------------------------------------------------------------------- /README.zh.hant.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | [中文] | [繁體中文] | [English] | [Todo] 4 |
5 | 6 |
7 | 8 | 9 | 動手做 | 現代CPP核心語言特性 - "強調動手實作的C++教學專案" 10 | 11 | [📚Book] + [🎥Video] + [⌨️Code] + [👥X] 12 |
13 | 14 | [中文]: README.zh.md 15 | [繁體中文]: README.zh.hant.md 16 | [English]: README.md 17 | [Todo]: README.md 18 | 19 | [📚Book]: https://sunrisepeak.github.io/mcpp-standard 20 | [🎥Video]: https://youtube.com/playlist?list=PL7uow6t1QjF0ooMLkLSS96swpSuBZvoRE&si=1xHOGVIYpbzZAosI 21 | [⌨️Code]: https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings 22 | [👥X]: https://forum.d2learn.org/category/20 23 | 24 | ## 目標 25 | 26 | - **`[掌握]`** - **現代C++核心的語言特性**及使用場景 27 | - **`[掌握]`** - 透過編譯器報錯資訊**定位問題的能力** 28 | - **`[熟悉]`** - 透過文件和[cppreference](https://cppreference.com)解決C++中不熟悉問題的能力 29 | - **`[了解]`** - 如何參與技術社群 - 開源專案的使用、提出問題、參與討論或貢獻 30 | 31 | > [!CAUTION] 32 | > 該項目當前處於開發初期, 如果你發現任何問題, 歡迎創建issues反饋或直接提交PR進行修復 33 | 34 | ## 快速開始 35 | 36 | > 嘗試 `Code -> Book -> Video -> X -> Code` 37 | 38 | ### 線上程式碼練習 39 | 40 | > [**點擊下方按鈕**](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 即可在雲端自動完成設定, 並進入練習程式碼偵測模式 41 | 42 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 43 | 44 | ### 建立本地練習環境 45 | 46 |
47 | 點選查看xlings安裝指令 48 | 49 | --- 50 | 51 | #### Linux/MacOS 52 | 53 | ```bash 54 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 55 | ``` 56 | 57 | #### Windows - PowerShell 58 | 59 | ```bash 60 | irm https://d2learn.org/xlings-install.ps1.txt | iex 61 | ``` 62 | 63 | > 註: xlings工具 -> [詳情](https://xlings.d2learn.org) 64 | 65 | --- 66 | 67 |
68 | 69 | ```bash 70 | xlings install d2x:mcpp-standard 71 | cd mcpp-standard 72 | d2x checker 73 | ``` 74 | 75 | **👉 [更多細節...](https://sunrisepeak.github.io/mcpp-standard/base/chapter_1.html)** 76 | 77 | ## 社區 78 | 79 | - **即時交流:** 167535744、1067245099 80 | - [**論壇版塊:**](https://forum.d2learn.org/category/20) 問題回饋、練習程式碼、技術交流與討論 81 | - **社區活動:** [📣 MSCP - mcpp計畫學習與貢獻者培養計畫](https://moga.d2learn.org/activity/mscp/intro.html) 82 | 83 | > **註:** 複雜性問題(技術、環境搭建等問題)推薦在論壇發文, 並詳細描述問題細節, 能更有效於問題的解決與復用 84 | 85 | ## 參與貢獻 86 | 87 | - **參與社群交流:** 回饋問題、參與社群問題討論、幫助社群新用戶解決問題 88 | - **參與專案維護與開發:** 參與社區中問題處理、修復Bug、多語言支援、[加入MSCP活動小組](https://moga.d2learn.org/activity/mscp/docs/join-group.html)、開發&最佳化新功能/模組 89 | 90 | **📑開源協議與貢獻許可(License & CLA)** 91 | 92 | - 本項目歡迎自由使用與分發!你可以在 [Apache License 2.0](LICENSE-CODE) 和 [CC-BY-NC-SA 4.0](LICENSE-BOOK) 協議下**免費**使用、修改和分享本專案的程式碼與文件內容 93 | - 如希望參與貢獻程式碼或文檔,請先閱讀[貢獻者授權協議(CLA)](CLA.md) 94 | 95 | **👥貢獻者** 96 | 97 | [![Star History Chart](https://api.star-history.com/svg?repos=Sunrisepeak/mcpp-standard&type=date&legend=top-left)](https://www.star-history.com/#Sunrisepeak/mcpp-standard&type=date&legend=top-left) 98 | 99 | 100 | 101 | 102 | 103 | Featured|HelloGitHub 104 | -------------------------------------------------------------------------------- /book/src/cpp11/13-long-long.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./13-long-long.html 7 | [English]: ../en/cpp11/13-long-long.html 8 | 9 | # long long - 64位整数类型 10 | 11 | `long long` 是C++11引入的**64位整数类型**,用于表示更大范围的整数值。它解决了传统整数类型在表示大整数时的范围限制问题。 12 | 13 | | Book | Video | Code | X | 14 | | --- | --- | --- | --- | 15 | | [cppreference](https://en.cppreference.com/w/cpp/language/types) / [markdown](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/13-long-long.md) | [视频解读]() | [练习代码](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/13-long-long-0.cpp) | | 16 | 17 | **为什么引入?** 18 | 19 | - 解决传统整数类型范围不足的问题 20 | - 提供统一的64位整数类型标准 21 | 22 | **long long和传统整数类型有什么区别?** 23 | 24 | - `long long` 保证至少64位宽度,范围至少为 -2^63 到 2^63-1 25 | - `int` 通常为32位,范围约为 -21亿到21亿 26 | - `long` 在32位系统上为32位,在64位系统上通常为64位(但标准只保证至少32位) 27 | 28 | ## 一、基础用法和场景 29 | 30 | ### 基本声明和初始化 31 | 32 | > 支持有符号和无符号, 以及字面量后缀标识 33 | 34 | ```cpp 35 | // 有符号long long 36 | long long val1 = 1; 37 | long long val2 = -1; 38 | 39 | // 无符号long long 40 | unsigned long long uVal1 = 1; 41 | 42 | // 字面量标识 + 类型推导 43 | auto longlong = 1LL: 44 | auto ulonglong = 1ULL; 45 | ``` 46 | 47 | ### 大整数应用和边界值 48 | 49 | > 处理超出传统整数类型范围的计算,基于边界值获取 50 | 51 | ```cpp 52 | //#include 53 | 54 | // 使用long long处理大数计算(超过int表示范围) 55 | long long population = 7800000000LL; // 世界人口 56 | 57 | // 获取整数类型边界 58 | int maxInt = std::numeric_limits::max(); 59 | long long maxLL = std::numeric_limits::max(); 60 | auto minLL = std::numeric_limits::min(); 61 | ``` 62 | 63 | ## 二、注意事项 64 | 65 | ### 类型推导和字面量后缀 66 | 67 | 使用`LL`或`ll`后缀明确指定`long long`字面量,使用`ULL`或`ull`指定无符号版本 68 | 69 | ```cpp 70 | auto num1 = 10000000000; // 类型可能是int或long,取决于编译器 71 | auto num2 = 10000000000LL; // 明确为long long辅助类型推导 72 | ``` 73 | 74 | ### 类型转换和精度问题 75 | 76 | 注意不同整数类型之间的转换可能导致的精度损失 77 | 78 | ```cpp 79 | long long bigValue = 3000000000LL; 80 | int smallValue = bigValue; // 可能溢出 81 | 82 | std::cout << "bigValue: " << bigValue << std::endl; 83 | std::cout << "smallValue: " << smallValue << std::endl; // 可能不正确 84 | 85 | // 安全转换检查 86 | if (bigValue > std::numeric_limits::max() || bigValue < std::numeric_limits::min()) { 87 | std::cout << "转换会导致溢出!" << std::endl; 88 | } 89 | ``` 90 | 91 | ### 位宽疑惑 - 标准中为什么不固定位宽? 92 | 93 | **原因** 94 | 95 | - **硬件差异问题:** 不同架构“自然字长”不同:16/32/64 位都有,大量嵌入式甚至只有 8/16 位乘除指令.若强行规定(long为64位),一些机器(32 位 MCU)上会造成巨大的性能损失 96 | - 例如: 在8位机器上做64位计算, 但没有相关的机器指令。所以需要通过算法模拟的方式实现, 进而导`指令周期`攀升 97 | - **历史与 ABI 兼容:** C/C++ 起源早于现代 32/64 位普及,许多平台的系统接口、文件格式、调用约定都已把 int/long 的大小写进了 ABI。标准若强制改变,会破坏二进制兼容和生态 98 | - **零成本抽象:** C/C++ 标准面向“与机器高效映射”的抽象机,只规定行为与最小范围,让实现能选择对该平台最自然的宽度,从而获得零开销抽象或接近零开销 99 | 100 | **解决方案** 101 | 102 | - **C/C++提供了可选方案:** 需要精确位宽时,可以使用`/`里的 `int8_t`、`int16_t`、`int32_t`、`int64_t`... 103 | - **不假设位宽和静态断言:** 开发时不假设类型的位宽, 从而提高可移植性. 如果部分代码做了位宽假设, 可以通过静态断言来保证位宽符合预期 `static_assert(sizeof(T)==N)` 104 | 105 | 106 | ![](../imgs/long-long.0.png) 107 | 108 | ## 三、练习代码 109 | 110 | ### 练习代码主题 111 | 112 | - 0 - [long long基础用法](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/13-long-long-0.cpp) 113 | - 1 - [long long大数应用和边界值](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/13-long-long-1.cpp) 114 | 115 | ### 练习代码自动检测命令 116 | 117 | ```bash 118 | d2x checker long-long 119 | ``` 120 | 121 | ## 四、其他 122 | 123 | - [交流讨论](https://forum.d2learn.org/category/20) 124 | - [mcpp-standard教程仓库](https://github.com/Sunrisepeak/mcpp-standard) 125 | - [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) 126 | - [教程支持工具-xlings](https://xlings.d2learn.org) 127 | -------------------------------------------------------------------------------- /videos/README.md: -------------------------------------------------------------------------------- 1 | # mcpp-standard 解读视频/动画 2 | 3 | ## 动画代码 4 | 5 | ```python 6 | # manim -pql videos/[cppxx]/[filename].py 7 | manim -pql videos/cpp11/09-list-initialization.py 8 | ``` 9 | 10 | > Note: Manim Community v0.18.1 11 | 12 | ## 视频列表 13 | 14 | | c++标准 | 特性 | 标题 | 练习代码/视频 | 备注 | 15 | | --- | --- | --- | --- | --- | 16 | | **引导** | `项目使用教程/引导` | hello mcpp | [docs](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/chapter_1.md) / [code](/dslings/hello-mcpp.cpp) / [video](https://www.bilibili.com/video/BV182MtzPEiX?p=2) | | 17 | | **cpp11** | `00 - auto和decltype` | 类型自动推导 | [docs](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md) / [code](/dslings/cpp11/00-auto-and-decltype-0.cpp) / [video](https://www.bilibili.com/video/BV1xkdYYUEyH) | | 18 | | | | decltype注意事项 | [code](/dslings/cpp11/00-auto-and-decltype-4.cpp) / [video](https://www.bilibili.com/video/BV1KWoMYUEzW) | [补充](https://forum.d2learn.org/topic/82) | 19 | | | `01 - default和delete` | 控制默认构造函数生成 | [code](/dslings/cpp11/01-default-and-delete-0.cpp) / [video](https://www.bilibili.com/video/BV1B35pz5EN2) | | 20 | | | | 类型对象行为控制示例 | [code](/dslings/cpp11/01-default-and-delete-1.cpp) / [video](https://www.bilibili.com/video/BV1Vg5tznE8o) | | 21 | | | `02 - override和final` | 重写显示意图和编译器检查 | [code](/dslings/cpp11/02-final-and-override-0.cpp) / [video](https://www.bilibili.com/video/BV1BdLJz6EKJ) | | 22 | | | | 继承和重现限制 | [code](/dslings/cpp11/02-final-and-override-1.cpp) / [video](https://www.bilibili.com/video/BV1H1jAzTEYT) | | 23 | | | `03 - 后置返回值类型` | 后置返回值类型基础用法 | [code](/dslings/cpp11/03-trailing-return-type.cpp) / [video](https://www.bilibili.com/video/BV1Ma5wzgE9h) | | 24 | | | `04 - 右值引用` | 临时对象生命周期延长的可变性质 | [code](/dslings/cpp11/04-rvalue-references.cpp) / [video](https://www.bilibili.com/video/BV1vn5wzmEVk) | | 25 | | | `05 - 移动语义` | 移动构造和触发时机 | [code](/dslings/cpp11/05-move-semantics-0.cpp) / [video](https://www.bilibili.com/video/BV19gj9zAERL) | | 26 | | | | 移动赋值和触发时机 | [code](/dslings/cpp11/05-move-semantics-1.cpp) / [video](https://www.bilibili.com/video/BV1NDjRzREsY) | | 27 | | | | 移动的不是对象而是资源 | [code](/dslings/cpp11/05-move-semantics-2.cpp) / [video](https://www.bilibili.com/video/BV1P9jRzXE3a) | | 28 | | | `06 - 作用域枚举` | 传统枚举的问题 | [code](/dslings/cpp11/06-scoped-enums-0.cpp) / [video](https://www.bilibili.com/video/BV1fn7iz4EuR) | | 29 | | | | 作用域枚举的基本用法 | [code](/dslings/cpp11/06-scoped-enums-1.cpp) / [video](https://www.bilibili.com/video/BV1fn7iz4EuR) | | 30 | | | `07 - constexpr` | const和constexpr有什么不同 | [code](/dslings/cpp11/07-constexpr-0.cpp) / [video](https://www.bilibili.com/video/BV1LRMLzgE4w) | | 31 | | | | 编译期计算应用示例 | [code](/dslings/cpp11/07-constexpr-1.cpp) / [video](https://www.bilibili.com/video/BV15CMEzLEuN) | | 32 | | | `08 - literal-type` | 什么是字面值类型 | [code](/dslings/cpp11/08-literal-type-0.cpp) / [video](https://www.bilibili.com/video/BV1h23UzvEX6) | [编译期加密库示例](https://github.com/Sunrisepeak/honly/blob/main/honly_jiami.hpp) | 33 | | | | 如何定义一个字面值类型 | [code](/dslings/cpp11/08-literal-type-1.cpp) / [video](https://www.bilibili.com/video/BV1h23UzvEX6) | | 34 | | | `09 - 列表初始化` | 现代C++初始化风格 | [code](/dslings/cpp11/09-list-initialization-0.cpp) / [video](https://www.bilibili.com/video/BV1vKuQzkEo2) | | 35 | | | | -> | [code1](/dslings/cpp11/09-list-initialization-1.cpp) / [code2](/dslings/cpp11/09-list-initialization-2.cpp) / [code3](/dslings/cpp11/09-list-initialization-3.cpp) | | 36 | | | `10 - 委托构造函数` | 委托构造基础用法和注意事项 | [code](/dslings/cpp11/10-delegating-constructors-0.cpp) / [video](https://www.bilibili.com/video/BV1zft3zSEER) | | 37 | | | | -> | [code1](/dslings/cpp11/10-delegating-constructors-1.cpp) | | 38 | | | `11 - 继承构造函数` | 继承构造函数的基础用法 | [code](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/11-inherited-constructors-0.cpp) / [video](https://www.bilibili.com/video/BV1bspBzFEEC) | | -------------------------------------------------------------------------------- /book/en/src/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 👉 📚 [中文] | [English] | [Github] 4 |
5 | 6 |
7 | 8 | 9 | D2X | Modern C++ Core Language Features - "A C++ tutorial project focused on practical" 10 | 11 | [📚Book] + [🎥Video] + [⌨️Code] + [👥X] 12 |
13 | 14 | [中文]: ../ 15 | [GITHUB]: https://github.com/Sunrisepeak/mcpp-standard 16 | [English]: ./ 17 | 18 | [📚Book]: https://sunrisepeak.github.io/mcpp-standard 19 | [🎥Video]: https://www.bilibili.com/video/BV182MtzPEiX 20 | [⌨️Code]: https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings 21 | [👥X]: https://forum.d2learn.org/category/20 22 | 23 | ## Goals 24 | 25 | - **`[Master]`** - **Core language features of Modern C++** and their usage scenarios 26 | - **`[Master]`** - The ability to **identify and debug issues** using compiler error messages 27 | - **`[Familiarize]`** - The ability to solve unfamiliar C++ problems using documentation and [cppreference](https://cppreference.com) 28 | - **`[Understand]`** - How to participate in the technical community — using open-source projects, asking questions, joining discussions, or contributing 29 | 30 | ## Quick Start 31 | 32 | > Try `Code -> Book -> Video -> X -> Code` 33 | 34 | ### Interactive Code Practice (Online) 35 | 36 | > [**click the button below**](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) to automatically complete the configuration in the cloud and enter the practice code detection mode 37 | 38 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 39 | 40 | ### Interactive Code Practice (Local) 41 | 42 |
43 | click to view xlings installation command 44 | 45 | --- 46 | 47 | #### Linux/MacOS 48 | 49 | ```bash 50 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 51 | ``` 52 | 53 | #### Windows - PowerShell 54 | 55 | ```bash 56 | irm https://d2learn.org/xlings-install.ps1.txt | iex 57 | ``` 58 | 59 | > tips: xlings -> [details](https://xlings.d2learn.org) 60 | 61 | --- 62 | 63 |
64 | 65 | ```bash 66 | xlings install d2x:mcpp-standard 67 | cd mcpp-standard 68 | d2x checker 69 | ``` 70 | 71 | **👉 [more details...](https://sunrisepeak.github.io/mcpp-standard/en/base/chapter_1.html)** 72 | 73 | ## Community 74 | 75 | - **groups:** [mcpp forum](https://forum.d2learn.org/category/20) 76 | - [**forum:**](https://forum.d2learn.org/category/20) issues feedback, practice code, technical discussions 77 | - **community activities:** [📣 MSCP - mcpp project learning and contributor training program](https://moga.d2learn.org/activity/mscp/intro.html) 78 | 79 | > **Note:** Complex issues (technical, environment setup, etc.) are recommended to be posted on the forum and detailed description of the problem can be more effective in problem solving and reuse. 80 | 81 | ## Contributing 82 | 83 | - **Community Communication:** Report issues, participate in community discussions, and help new users solve problems. 84 | - **Project Maintenance and Development:** Participate in community issue resolution, bug fixes, multilingual support, [join the MSCP activity group](https://moga.d2learn.org/activity/mscp/docs/join-group.html), and develop and optimize new features and modules. 85 | 86 | **📑License & CLA** 87 | 88 | - This project welcomes free use and distribution! You may use, modify, and share the code and documentation in this project **free** under the [Apache License 2.0](LICENSE-CODE) and [CC-BY-NC-SA 4.0](LICENSE-BOOK) licenses. 89 | - If you would like to contribute code or documentation, please read the [Contributor License Agreement (CLA)](CLA.md) first. 90 | 91 | **👥Contributors** 92 | 93 | 94 | 95 | 96 | 97 | Featured|HelloGitHub 98 | -------------------------------------------------------------------------------- /book/src/cpp11/00-auto-and-decltype.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./00-auto-and-decltype.html 7 | [English]: ../en/cpp11/00-auto-and-decltype.html 8 | 9 | # 类型自动推导 - auto和decltype 10 | 11 | auto 和 decltype 是C++11引入的强有力的**类型自动推导**工具. 不仅让代码变的更加简洁, 还增强了模板和泛型的表达能力 12 | 13 | | Book | Video | Code | X | 14 | | --- | --- | --- | --- | 15 | | [cppreference-auto](https://en.cppreference.com/w/cpp/language/auto) / [cppreference-decltype](https://en.cppreference.com/w/cpp/language/decltype) / [markdown](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/00-auto-and-decltype.md) | [视频解读](https://www.bilibili.com/video/BV1xkdYYUEyH) | [练习代码](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/00-auto-and-decltype-0.cpp) | | 16 | 17 | 18 | **为什么引入?** 19 | 20 | - 解决类型声明过于复杂的问题 21 | - 模板应用中, 获取对象或表达式类型的需求 22 | - 为lambda表达式的定义做支撑 23 | 24 | **auto和decltype有什么区别?** 25 | 26 | - auto常常用于变量定义, 推导的类型可能丢失const或引用(可显示指定进行保留auto &) 27 | - decltype获取表达式的**精确类型** 28 | - auto通常无法作为模板类型参数使用 29 | 30 | ## 一、基础用法和场景 31 | 32 | ### 声明定义 33 | 34 | > 充当类型站位符, 辅助变量的定义或声明。使用auto时变量必须要初始化, decltype可以不用初始化 35 | 36 | ```cpp 37 | int b = 2; 38 | auto b1 = b; 39 | decltype(b) b2 = b; 40 | decltype(b) b3; // 可以不用初始化 41 | ``` 42 | 43 | ### 表达式类型推导 44 | 45 | > 常常用于复杂表达式的类型推导, 确保计算精度 46 | 47 | ```c++ 48 | int a = 1; 49 | 50 | auto b1 = a + 2; 51 | decltype(a + 2 + 1.1) b2 = a + 2 + 1.1; 52 | 53 | auto c1 = a + '0'; 54 | decltype(2 + 'a') c2 = 2 + 'a'; 55 | ``` 56 | 57 | ### 复杂类型推导 58 | 59 | **迭代器类型推导** 60 | 61 | ```c++ 62 | std::vector v = {1, 2, 3}; 63 | 64 | auto it = v.begin(); // 自动推导it类型 65 | // decltype(v.begin()) it = v.begin(); 66 | for (; it != v.end(); ++it) { 67 | std::cout << *it << " "; 68 | } 69 | ``` 70 | 71 | **函数类型推导** 72 | 73 | > 对于函数或lambda表达式这种复杂类型, 常常使用auto和decltype. 一般, lambda定义用auto, 模板类型参数用decltype 74 | 75 | ```c++ 76 | int add_func(int a, int b) { 77 | return a + b; 78 | } 79 | 80 | int main() { 81 | auto minus_func = [](int a, int b) { return a - b; }; 82 | 83 | std::vector> funcVec = { 84 | add_func, 85 | minus_func 86 | }; 87 | 88 | funcVec[0](1, 2); 89 | funcVec[1](1, 2); 90 | //... 91 | } 92 | ``` 93 | 94 | ### 函数返回值类型推导 95 | 96 | **语法糖用法** 97 | 98 | > auto为后置返回类型函数定义写法做支持, 并可以配合decltype进行返回类型推导使用 99 | 100 | ```cpp 101 | auto main() -> int { 102 | return 0; 103 | } 104 | 105 | auto add(int a, double b) -> decltype(a + b) { 106 | return a + b; 107 | } 108 | ``` 109 | 110 | **函数模板返回值类型推导** 111 | 112 | > 当无法确定模板返回值时可以用auto + decltype做推导, 可以让add支持一般类型int, double,... 和 复杂类型 Point, Vec,... 增强泛型的表达能力. (c++14中可以省略decltype) 113 | 114 | ```cpp 115 | template 116 | auto add(T1 a, T2 b) -> decltype(a + b) { 117 | return a + b; 118 | } 119 | ``` 120 | 121 | ### 类/结构体成员类型推导 122 | 123 | ```cpp 124 | struct Object { 125 | const int a; 126 | double b; 127 | Object() : a(1), b(2.0) { } 128 | }; 129 | 130 | int main() { 131 | const Object obj; 132 | 133 | auto a = obj.a; 134 | std::vector vec; 135 | } 136 | ``` 137 | 138 | ## 二、注意事项 - 括号带来的影响 139 | 140 | ### decltype(obj) 和 decltype( (obj) )的区别 141 | 142 | - 一般`decltype(obj)`获取的时其声明类型 143 | - 而`decltype( (obj) )` 获取的是 `(obj)` 这个表达式的类型(左值表达式) 144 | 145 | ```cpp 146 | int a = 1; 147 | decltype(a) b; // 推导结果为a的声明类型int 148 | decltype( (a) ) c; // 推导结果为(a)这个左值表达式的类型 int & 149 | ``` 150 | 151 | ### decltype(obj.b) 和 decltype( (obj.b) )的区别 152 | 153 | - `decltype( (obj.b) )`: 从表达式视角做类型推导, obj定义类型会影响推导结果. 例如, 如果obj被const修饰时, const会限定obj.b的访问为const 154 | - `decltype(obj.b)`: 由于推导的是成员声明类型, 所以不会受obj定义的影响 155 | 156 | ```cpp 157 | struct Object { 158 | const int a; 159 | double b; 160 | Object() : a(1), b(2.0) { } 161 | }; 162 | 163 | int main() { 164 | Object obj; 165 | const Object obj1; 166 | 167 | decltype(obj.b) // double 168 | decltype(obj1.b) // double 169 | 170 | decltype( (obj.b) ) // double & 171 | decltype( (obj1.b) ) // 受obj1定义的const修饰影响, 所以是 const double & 172 | } 173 | ``` 174 | 175 | ### 右值引用变量, 在表达式中是左值 176 | 177 | ```cpp 178 | int &&b = 1; 179 | 180 | decltype(b) // 推导结果是声明类型 int && 181 | decltype( (b) ) // 推导结果是 int & 182 | ``` 183 | 184 | ## 三、其他 185 | 186 | - [交流讨论](https://forum.d2learn.org/category/20) 187 | - [mcpp-standard教程仓库](https://github.com/Sunrisepeak/mcpp-standard) 188 | - [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) 189 | - [教程支持工具-xlings](https://github.com/d2learn/xlings) -------------------------------------------------------------------------------- /book/src/cpp11/09-list-initialization.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./09-list-initialization.html 7 | [English]: ../en/cpp11/09-list-initialization.html 8 | 9 | # 列表初始化 10 | 11 | 列表初始是一种用`{ arg1, arg2, ... }`列表(大括号), 初始化对象的一种初始化风格, 并且可以用于几乎所有的对象初始化场景, 所以也常常称他为**统一初始化**。此外, 他还增加了列表成员的类型检查功能, 防止一些窄化问题 12 | 13 | | Book | Video | Code | X | 14 | | --- | --- | --- | --- | 15 | | [cppreference](https://en.cppreference.com/w/cpp/language/list_initialization.html) / [markdown](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/09-list-initialization.md) | [视频解读](https://www.bilibili.com/video/BV1vKuQzkEo2) | [练习代码](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/09-list-initialization-0.cpp) | | 16 | 17 | **为什么引入?** 18 | 19 | - 解决初始化语法风格不统一问题 20 | - 禁止隐式转换造成的窄化问题 21 | - 方便容器类型的初始化 22 | - 解决默认初始化语法陷阱 23 | 24 | ## 一、基础用法和场景 25 | 26 | ### 统一初始化风格 27 | 28 | c++11之前不同场景有不同的初始化的方式 29 | 30 | ```cpp 31 | int a = 5; // 拷贝初始化 32 | int b(5); // 直接初始化 33 | int arr[3] = {1, 2, 3}; // 数组初始化 34 | Object obj1; // 默认构造 35 | Object obj2(obj1); // 拷贝构造 36 | ``` 37 | 38 | 他们可以用`{ }`进行风格统一 39 | 40 | ```cpp 41 | int a = { 5 }; // 拷贝初始化 42 | int b { 5 }; // 直接初始化 43 | int arr[3] = {1, 2, 3}; // 数组初始化 44 | Object obj1 { }; // 默认初始化 45 | Object obj2 { obj1 }; // 拷贝构造 46 | ``` 47 | 48 | ### 避免隐式类型转换和窄化问题 49 | 50 | 一般传统的初始化方法, 是默认C语言隐式类型转换规则风格. 例如, 用`double`类型初始化`int`类型变量的时候会自动丢掉小数位. 而列表初始化会增加额外的编译期类型检查来避免隐式类型转换和精度丢失问题. 在现代C++中, 除非有意的需要这种隐式类型转换, 大多数时候使用列表初始化是更好的选择 51 | 52 | ```cpp 53 | int a = 3.3; // ok 54 | int a = { 3.3 }; // error 55 | 56 | constexpr double b { 3.3 }; // ok 57 | int c(b); // ok -> 3 58 | int c { b }; // error: 类型不匹配 59 | ``` 60 | 61 | 数组初始化中的窄化检查 62 | 63 | ```cpp 64 | int arr[] { 1, 2, 3.3, 4 }; // error: 3.3会发生窄化 65 | int arr[] = { 1, 2, b, 4 }; // error: b会发生窄化 66 | ``` 67 | 68 | > 注: 如果b是运行时变量, 编译期可能只会触发窄化警告而不会报错 69 | 70 | ### 提高容器初始化的简洁性 71 | 72 | 对于容器类型的初始化, 老C++中常常会分成两个步骤。第一步, 创建一个元素数组; 第二步, 使用这个数组来初始化容器 73 | 74 | ```cpp 75 | int arr[5] = {1, 2, 3, 4, 5}; 76 | std::vector v(arr, arr + sizeof(arr) / sizeof(int)); 77 | ``` 78 | 79 | 而列表初始化的引入, 能让我们把两步合为一个步骤, 大幅度提高了容器初始化的简洁性 80 | 81 | ```cpp 82 | std::vector v1 {1, 2, 3}; 83 | std::vector v2 {1, 2, 3, 4, 3}; 84 | ``` 85 | 86 | 并且, 可以通过`std::initializer_list`让我们的自定义类型也能支持这种**不定长**的列表初始化方式 87 | 88 | ```cpp 89 | class MyVector { 90 | public: 91 | MyVector() = default; 92 | MyVector(std::initializer_list list) { 93 | for (auto it = list.begin(); it != list.end(); it++) { 94 | // *it ... 95 | } 96 | } 97 | }; 98 | ``` 99 | 100 | ```cpp 101 | MyVector v1 {1, 2, 3}; 102 | MyVector v2 {1, 2, 3, 4, 3}; 103 | ``` 104 | 105 | ### 避免初始化语法陷阱 106 | 107 | 使用`{ }`调用默认构造函数, 避免语法陷阱 108 | 109 | ```cpp 110 | #include 111 | 112 | struct Object { 113 | Object() { std::cout << "Constructor called!" << std::endl; } 114 | }; 115 | 116 | int main() { 117 | Object obj1 { }; 118 | Object obj2(); // obj2是函数, 而不是Object对象 119 | } 120 | ``` 121 | 122 | ## 二、注意事项 123 | 124 | ### 数组类型列表初始化 125 | 126 | 数组类型的定义里面的值一般是不确定的, 但是列表初始化的方式会做默认值的初始化, 并支持自动补0 127 | 128 | 普通数组 129 | 130 | ```cpp 131 | int arr[4]; // arr[0] 不确定 132 | int arr[4] { }; // arr[0] = 0 133 | int arr[4] { 1, 2 }; // arr[2] / arr[3] 会自动补成0 134 | ``` 135 | 136 | 数组容器 137 | 138 | ```cpp 139 | std::array arr; // arr[0] 不确定/可能是随机值 140 | std::array arr { }; // arr[0] == 0 141 | std::array arr { 1, 2 }; // arr[0] == 1, arr[2] 会自动补成0 142 | ``` 143 | 144 | ### 成员初始化问题 145 | 146 | 列表初始化支持直接对 聚合类型的成员做初始化, 但需要注意添加构造函数后必须要匹配构造函数才可以 147 | 148 | ```cpp 149 | struct Point { 150 | int x, y; 151 | // Point(int x, int y) { ... } 152 | }; 153 | ``` 154 | 155 | ```cpp 156 | Point { 1, 2 }; 157 | Point p1 { 2, 3 }; // p1 { x: 2, y: 3} 158 | ``` 159 | 160 | ### 优先匹配`std::initializer_list`的构造函数 161 | 162 | ```cpp 163 | class MyVector { 164 | public: 165 | MyVector() = default; 166 | MyVector(int x, int y) { } 167 | MyVector(std::initializer_list list) { 168 | for (auto it = list.begin(); it != list.end(); it++) { 169 | // *it ... 170 | } 171 | } 172 | }; 173 | ``` 174 | 175 | ```cpp 176 | MyVector v1 { 1, 2 }; // 会优先匹配 MyVector(std::initializer_list list) 177 | MyVector v1(1, 2); // 匹配MyVector(int x, int y) 178 | ``` 179 | 180 | ## 三、其他 181 | 182 | - [交流讨论](https://forum.d2learn.org/category/20) 183 | - [mcpp-standard教程仓库](https://github.com/Sunrisepeak/mcpp-standard) 184 | - [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) 185 | - [教程支持工具-xlings](https://github.com/d2learn/xlings) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | [中文] | [繁體中文] | [English] | [Todo] 4 |
5 | 6 |
7 | 8 | 9 | D2X | Modern C++ Core Language Features - "A C++ tutorial project focused on practical" 10 | 11 | [📚Book] + [🎥Video] + [⌨️Code] + [👥X] 12 |
13 | 14 | [中文]: README.zh.md 15 | [繁體中文]: README.zh.hant.md 16 | [English]: README.md 17 | [Todo]: README.md 18 | 19 | [📚Book]: https://sunrisepeak.github.io/mcpp-standard/en/index.html 20 | [🎥Video]: https://youtube.com/playlist?list=PL7uow6t1QjF0ooMLkLSS96swpSuBZvoRE&si=1xHOGVIYpbzZAosI 21 | [⌨️Code]: https://github.com/Sunrisepeak/mcpp-standard/tree/main/dslings 22 | [👥X]: https://forum.d2learn.org/category/20 23 | 24 | ## Goals 25 | 26 | - **`[Master]`** - **Core language features of Modern C++** and their usage scenarios 27 | - **`[Master]`** - The ability to **identify and debug issues** using compiler error messages 28 | - **`[Familiarize]`** - The ability to solve unfamiliar C++ problems using documentation and [cppreference](https://cppreference.com) 29 | - **`[Understand]`** - How to participate in the technical community — using open-source projects, asking questions, joining discussions, or contributing 30 | 31 | > [!CAUTION] 32 | > This project is currently in its early development stage. If you encounter any issues, feel free to create an issue for feedback or directly submit a PR to fix it. 33 | 34 | ## Quick Start 35 | 36 | > Try `Code -> Book -> Video -> X -> Code` 37 | 38 | ### Interactive Code Practice (Online) 39 | 40 | > [**click the button below**](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) to automatically complete the configuration in the cloud and enter the practice code detection mode 41 | 42 | [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=Sunrisepeak/mcpp-standard) 43 | 44 | ### Interactive Code Practice (Local) 45 | 46 |
47 | click to view xlings installation command 48 | 49 | --- 50 | 51 | #### Linux/MacOS 52 | 53 | ```bash 54 | curl -fsSL https://d2learn.org/xlings-install.sh | bash 55 | ``` 56 | 57 | #### Windows - PowerShell 58 | 59 | ```bash 60 | irm https://d2learn.org/xlings-install.ps1.txt | iex 61 | ``` 62 | 63 | > tips: xlings -> [details](https://xlings.d2learn.org) 64 | 65 | --- 66 | 67 |
68 | 69 | ```bash 70 | xlings install d2x:mcpp-standard 71 | cd mcpp-standard 72 | d2x checker 73 | ``` 74 | 75 | **👉 [more details...](https://sunrisepeak.github.io/mcpp-standard/base/chapter_1.html)** 76 | 77 | ## Community 78 | 79 | - **groups:** [mcpp forum](https://forum.d2learn.org/category/20) 80 | - [**forum:**](https://forum.d2learn.org/category/20) issues feedback, practice code, technical discussions 81 | - **community activities:** [📣 MSCP - mcpp project learning and contributor training program](https://moga.d2learn.org/activity/mscp/intro.html) 82 | 83 | > **Note:** Complex issues (technical, environment setup, etc.) are recommended to be posted on the forum and detailed description of the problem can be more effective in problem solving and reuse. 84 | 85 | ## Contributing 86 | 87 | - **Community Communication:** Report issues, participate in community discussions, and help new users solve problems. 88 | - **Project Maintenance and Development:** Participate in community issue resolution, bug fixes, multilingual support, [join the MSCP activity group](https://moga.d2learn.org/activity/mscp/docs/join-group.html), and develop and optimize new features and modules. 89 | 90 | **📑License & CLA** 91 | 92 | - This project welcomes free use and distribution! You may use, modify, and share the code and documentation in this project **free** under the [Apache License 2.0](LICENSE-CODE) and [CC-BY-NC-SA 4.0](LICENSE-BOOK) licenses. 93 | - If you would like to contribute code or documentation, please read the [Contributor License Agreement (CLA)](CLA.md) first. 94 | 95 | **👥Contributors** 96 | 97 | [![Star History Chart](https://api.star-history.com/svg?repos=Sunrisepeak/mcpp-standard&type=date&legend=top-left)](https://www.star-history.com/#Sunrisepeak/mcpp-standard&type=date&legend=top-left) 98 | 99 | 100 | 101 | 102 | 103 | Featured|HelloGitHub 104 | -------------------------------------------------------------------------------- /book/src/cpp11/12-nullptr.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | 🌎 [中文] | [English] 4 |
5 | 6 | [中文]: ./12-nullptr.html 7 | [English]: ../en/cpp11/12-nullptr.html 8 | 9 | # nullptr - 指针字面量 10 | 11 | `nullptr` 是C++11引入的**指针字面量**,用于表示空指针。它解决了传统空指针表示方式(如`NULL`和`0`)在类型安全性和重载解析方面的不足。 12 | 13 | | Book | Video | Code | X | 14 | | --- | --- | --- | --- | 15 | | [cppreference](https://en.cppreference.com/w/cpp/language/nullptr) / [markdown](https://github.com/Sunrisepeak/mcpp-standard/blob/main/book/src/cpp11/12-nullptr.md) | [视频解读]() | [练习代码](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-0.cpp) | | 16 | 17 | **为什么引入?** 18 | 19 | - 解决`NULL`宏和整数`0`在重载解析中的歧义问题 20 | - 提供类型安全的空指针表示方式 21 | - 明确区分指针和整数类型 22 | - 支持模板编程中的类型推导 23 | 24 | **nullptr和NULL有什么区别?** 25 | 26 | - `nullptr`是C++11引入的关键字,类型为`std::nullptr_t` 27 | - `NULL`是预处理宏,通常定义为整数`0`或`(void*)0` 28 | - `nullptr`在重载解析中更精确,不会与整数类型混淆 29 | 30 | ## 一、基础用法和场景 31 | 32 | ### 替代NULL和0 33 | 34 | > 用于指针变量的初始化和赋值,替代传统的`NULL`和`0` 35 | 36 | ```cpp 37 | int* ptr1 = nullptr; // 推荐用法 38 | int* ptr2 = NULL; // 传统用法 39 | int* ptr3 = 0; // 不推荐 40 | 41 | // 检查指针是否为空 42 | if (ptr1 == nullptr) { 43 | // 处理空指针情况 44 | } 45 | ``` 46 | 47 | ### 解决重载歧义问题 48 | 49 | > 在函数调用中明确传递空指针,`nulltpr`能避免重载歧义问题, 并且避免与整数类型的混淆 50 | 51 | ```cpp 52 | void func(int* ptr) { 53 | if (ptr != nullptr) { 54 | *ptr = 42; 55 | } 56 | } 57 | 58 | void func(int value) { 59 | // 处理整数参数 60 | } 61 | 62 | int main() { 63 | func(nullptr); // 明确调用指针版本 64 | func(0); // 可能调用整数版本,产生歧义 65 | func(NULL); // 可能调用整数版本,产生歧义 66 | } 67 | ``` 68 | 69 | 例如上面的代码中,调用`func(NULL)`就会报重载歧义错误 70 | 71 | ```bash 72 | main.cpp: In function 'int main()': 73 | main.cpp:16:9: error: call of overloaded 'func(NULL)' is ambiguous 74 | 16 | func(NULL); // 可能调用整数版本,产生歧义 75 | | ~~~~^~~~~~ 76 | ``` 77 | 78 | ### 确保模板编程中的类型安全 79 | 80 | > 在模板函数和类中,`nullptr`提供更好的类型推导和安全性 81 | 82 | ```cpp 83 | // https://en.cppreference.com/w/cpp/language/nullptr.html 84 | 85 | template 86 | constexpr T clone(const T& t) { 87 | return t; 88 | } 89 | 90 | void g(int*) { 91 | std::cout << "Function g called\n"; 92 | } 93 | 94 | int main() { 95 | g(nullptr); // ok 96 | g(NULL); // ok 97 | g(0); // ok 98 | 99 | g(clone(nullptr)); // ok 100 | g(clone(NULL)); // ERROR: NULL可能会被推导成非"指针"类型 101 | g(clone(0)); // ERROR: 0会被推导成非"指针"类型 102 | } 103 | ``` 104 | 105 | 当使用函数模板时, `NULL`和`0`通过会被推导成非"指针"类型, 而`nullptr`可以避免这个问题 106 | 107 | ```bash 108 | main.cpp:19:12: error: invalid conversion from 'int' to 'int*' [-fpermissive] 109 | 19 | g(clone(0)); // ERROR: 0会被推导成非"指针"类型 110 | | ~~~~~^~~ 111 | | | 112 | | int 113 | ``` 114 | 115 | ### 智能指针和容器 116 | 117 | > 与现代C++特性(如智能指针、STL容器)配合使用 118 | 119 | ```cpp 120 | #include 121 | #include 122 | 123 | int main() { 124 | std::shared_ptr sp1 = nullptr; 125 | std::unique_ptr up1 = nullptr; 126 | 127 | std::vector vec; 128 | vec.push_back(nullptr); 129 | 130 | // 检查智能指针是否为空 131 | if (sp1 == nullptr) { 132 | sp1 = std::make_shared(42); 133 | } 134 | } 135 | ``` 136 | 137 | ## 二、注意事项 138 | 139 | ### 类型推导和std::nullptr_t 140 | 141 | `nullptr`的类型是`std::nullptr_t`,这是一个特殊的类型,可以 **隐式** 转换为任何指针类型: 142 | 143 | ```cpp 144 | #include // 包含std::nullptr_t的定义 145 | 146 | void func(int*) {} 147 | void func(double*) {} 148 | void func(std::nullptr_t) {} 149 | 150 | int main() { 151 | auto ptr = nullptr; // ptr的类型是std::nullptr_t 152 | 153 | func(nullptr); // 调用std::nullptr_t版本 154 | func(ptr); // 调用std::nullptr_t版本 155 | 156 | int* intPtr = nullptr; 157 | func(intPtr); // 调用int*版本 158 | } 159 | ``` 160 | 161 | ### 与布尔类型的隐式转换 162 | 163 | `nullptr`可以隐式转换为`bool`类型,在条件判断中非常方便: 164 | 165 | ```cpp 166 | int* ptr = nullptr; 167 | 168 | if (ptr) { // 等价于 if (ptr != nullptr) 169 | // 指针非空 170 | } else { 171 | // 指针为空 172 | } 173 | 174 | bool isEmpty = (ptr == nullptr); // true 175 | ``` 176 | 177 | ## 三、练习代码 178 | 179 | ### 练习代码主题 180 | 181 | - 0 - [nullptr基础用法](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-0.cpp) 182 | - 1 - [nullptr的函数重载](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-1.cpp) 183 | - 2 - [nullptr在模板编程中的优势](https://github.com/Sunrisepeak/mcpp-standard/blob/main/dslings/cpp11/12-nullptr-2.cpp) 184 | 185 | ### 练习代码自动检测命令 186 | 187 | ```bash 188 | d2x checker nullptr 189 | ``` 190 | 191 | ## 四、其他 192 | 193 | - [交流讨论](https://forum.d2learn.org/category/20) 194 | - [mcpp-standard教程仓库](https://github.com/Sunrisepeak/mcpp-standard) 195 | - [教程视频列表](https://space.bilibili.com/65858958/lists/5208246) 196 | - [教程支持工具-xlings](https://xlings.d2learn.org) 197 | --------------------------------------------------------------------------------