From 6f8a44c4290e155743d973459fd9af821a82da3b Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 14:21:00 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E6=9C=80=E5=8D=A2=E7=9A=84=E7=91=9F's=20ho?= =?UTF-8?q?mework?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .../\347\254\25401\351\242\230/brian.cpp" | 24 ++++++ .../\347\254\25404\351\242\230/brian.cpp" | 34 ++++++++ .../\347\254\25405\351\242\230/brian.cpp" | 86 +++++++++++++++++++ .../\347\254\25406\351\242\230/brian.md" | 5 ++ 5 files changed, 150 insertions(+) create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25401\351\242\230/brian.cpp" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/brian.cpp" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" diff --git a/.gitignore b/.gitignore index e85692fe..a956a476 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ node_modules /public /resources go.sum +cmake-build \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25401\351\242\230/brian.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25401\351\242\230/brian.cpp" new file mode 100644 index 00000000..73a9d1a8 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25401\351\242\230/brian.cpp" @@ -0,0 +1,24 @@ +// +// loser_homework / brian.cpp +// Created by brian on 2024 Apr 03. +// + +#include +#include +#include +#include + +template +requires std::invocable +std::vector& operator|(std::vector& vec, Func const& func) { + std::ranges::for_each(vec, func); + return vec; +} + + +int main() { + std::vector v{1, 2, 3}; + std::function f{[](const int& i) { std::cout << i << ' '; }}; + auto f2 = [](int& i) { i *= i; }; + v | f2 | f; +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/brian.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/brian.cpp" new file mode 100644 index 00000000..1d9430dd --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/brian.cpp" @@ -0,0 +1,34 @@ +// +// loser_homework / brian.cpp +// Created by brian on 2024 Apr 03. +// +#include + +class ComponentBase { +protected: + static inline std::size_t component_type_count = 0; +}; + +template +class Component : public ComponentBase { +public: + static size_t component_type_id() { + static size_t unique_id = component_type_count++; + return unique_id; + } +}; + +class A : public Component {}; + +class B : public Component {}; + +class C : public Component {}; + +int main() { + std::cout << A::component_type_id() << std::endl; + std::cout << B::component_type_id() << std::endl; + std::cout << B::component_type_id() << std::endl; + std::cout << A::component_type_id() << std::endl; + std::cout << A::component_type_id() << std::endl; + std::cout << C::component_type_id() << std::endl; +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" new file mode 100644 index 00000000..f895d07e --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" @@ -0,0 +1,86 @@ +// +// loser_homework / scope_guard.cpp +// Created by brian on 2024 Apr 03. +// +#include +#include + +#include +#include + +struct X { + X() { puts("X()"); } + + X(const X&) { puts("X(const X&)"); } + + X(X&&) noexcept { puts("X(X&&)"); } + + ~X() { puts("~X()"); } +}; + +struct scope_guard { + template + requires std::invocable + scope_guard(F&& func, A&& ...args) { + gc = [&func, &args...]() mutable { + /** + * @brief https://en.cppreference.com/w/cpp/utility/functional/invoke + * invoke: 如果\p func 是成员函数, 则\p ...args 的第一个参数是对应的对象(\p &,* ) + */ + std::invoke(std::forward(func), args...); + }; + } + ~scope_guard() { gc(); } + scope_guard(const scope_guard&) = delete; + scope_guard& operator=(const scope_guard&) = delete; + +private: + std::function gc; +}; + + +int main() { + { + // scope_guard的作用之一,是让各种C风格指针接口作为局部变量时也能得到RAII支持 + // 这也是本题的基础要求 + FILE* fp = nullptr; + try { + fp = fopen("test.txt", "a"); + auto guard = scope_guard([&] { + fclose(fp); + fp = nullptr; + }); + + throw std::runtime_error{"Test"}; + } catch (std::exception& e) { + puts(e.what()); + } + assert(fp == nullptr); + } + puts("----------"); + { + // 附加要求1,支持函数对象调用 + struct Test { + void operator()(X* x) { + delete x; + } + } t; + auto x = new X{}; + auto guard = scope_guard(t, x); + } + puts("----------"); + { + // 附加要求2,支持成员函数和std::ref + auto x = new X{}; + { + struct Test { + void f(X*& px) { + delete px; + px = nullptr; + } + } t; + auto guard = scope_guard{&Test::f, &t, std::ref(x)}; + } + assert(x == nullptr); + } +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" new file mode 100644 index 00000000..7dfe1176 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" @@ -0,0 +1,5 @@ +为保证atomic对象的原子性,复制和移动都是不允许的。 + +C++17之前 `std::atomic n = 6;`不合法是因为atomic只支持列表初始化, 写成 `std::atomic n = {6};`就可以通过编译了; + +17+之后的`std::atomic n = 6;`其实是原地构造,合法。 \ No newline at end of file From 22d41a14732a04d72d57ca804eb2134c4fa64efb Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 14:27:05 +0800 Subject: [PATCH 2/7] =?UTF-8?q?markdown=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/brian.md" | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" index 7dfe1176..feac9401 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" @@ -1,5 +1,5 @@ -为保证atomic对象的原子性,复制和移动都是不允许的。 +为保证 atomic 对象的原子性,复制和移动都是不允许的。 -C++17之前 `std::atomic n = 6;`不合法是因为atomic只支持列表初始化, 写成 `std::atomic n = {6};`就可以通过编译了; +C++17之前 `std::atomic n = 6;` 不合法是因为atomic只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了 -17+之后的`std::atomic n = 6;`其实是原地构造,合法。 \ No newline at end of file +17+之后的`std::atomic n = 6;` 其实是原地构造,合法。 \ No newline at end of file From 1098424d4d6012792bef4be87bde4b959728805e Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 15:53:12 +0800 Subject: [PATCH 3/7] =?UTF-8?q?markdown=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/brian.md" | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" index feac9401..b72052e1 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" @@ -1,5 +1 @@ -为保证 atomic 对象的原子性,复制和移动都是不允许的。 - -C++17之前 `std::atomic n = 6;` 不合法是因为atomic只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了 - -17+之后的`std::atomic n = 6;` 其实是原地构造,合法。 \ No newline at end of file +为保证 atomic 对象的原子性,复制和移动都是不允许的。 C++17之前 `std::atomic n = 6;` 不合法是因为 atomic 只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了。17+之后的`std::atomic n = 6;` 其实是原地构造,合法。 From 37150e47fa242c2480e7fdc78a373bbf200efcc6 Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 15:55:36 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=81=A2=E5=A4=8D.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- .../\347\254\25406\351\242\230/brian.md" | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index a956a476..ef796773 100644 --- a/.gitignore +++ b/.gitignore @@ -27,5 +27,4 @@ cmake-build-* node_modules /public /resources -go.sum -cmake-build \ No newline at end of file +go.sum \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" index b72052e1..b0ca8360 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" @@ -1 +1,3 @@ -为保证 atomic 对象的原子性,复制和移动都是不允许的。 C++17之前 `std::atomic n = 6;` 不合法是因为 atomic 只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了。17+之后的`std::atomic n = 6;` 其实是原地构造,合法。 +为保证 atomic 对象的原子性,复制和移动都是不允许的。 +C++17之前 `std::atomic n = 6;` 不合法是因为 atomic 只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了。 +17+之后的 `std::atomic n = 6;` 其实是原地构造,也不涉及任何复制移动,合法。 From ff9e25552c2f15f1e5979b79e76c154fdc6b204f Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 16:00:10 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=81=A2=E5=A4=8D.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ef796773..e85692fe 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,4 @@ cmake-build-* node_modules /public /resources -go.sum \ No newline at end of file +go.sum From e482dbcb09209e58c9360f5b597fec2b62ebf618 Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 16:45:39 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25405\351\242\230/brian.cpp" | 2 +- .../\347\254\25406\351\242\230/brian.md" | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" index f895d07e..9f6db136 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/brian.cpp" @@ -27,7 +27,7 @@ struct scope_guard { * @brief https://en.cppreference.com/w/cpp/utility/functional/invoke * invoke: 如果\p func 是成员函数, 则\p ...args 的第一个参数是对应的对象(\p &,* ) */ - std::invoke(std::forward(func), args...); + std::invoke(std::forward(func), std::forward(args)...); }; } ~scope_guard() { gc(); } diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" index b0ca8360..0afd534f 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" @@ -1,3 +1,5 @@ -为保证 atomic 对象的原子性,复制和移动都是不允许的。 -C++17之前 `std::atomic n = 6;` 不合法是因为 atomic 只支持列表初始化, 写成 `std::atomic n = {6};` 就可以通过编译了。 -17+之后的 `std::atomic n = 6;` 其实是原地构造,也不涉及任何复制移动,合法。 +在C++17及之后 `std::atomic n = 6;` 可以通过编译,主要是因为C++17引入了对复制消除的强制要求, +允许从基础类型直接初始化 `std::atomic` 对象, 即使 `std::atomic` 的复制构造函数被删除。 + +在C++17之前, 这种初始化因为尝试调用被删除的复制构造函数而失败。 +这个例子其实展示的是C++17改进了直接初始化和复制消除的规则,而不是传统意义上的RVO。 From a247eefa1ec4a0ac9aef6cc40ef4f3a78a699541 Mon Sep 17 00:00:00 2001 From: corgile Date: Thu, 4 Apr 2024 17:06:18 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=92=A4=E5=9B=9E=E9=94=99=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/brian.md" | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" deleted file mode 100644 index 0afd534f..00000000 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/brian.md" +++ /dev/null @@ -1,5 +0,0 @@ -在C++17及之后 `std::atomic n = 6;` 可以通过编译,主要是因为C++17引入了对复制消除的强制要求, -允许从基础类型直接初始化 `std::atomic` 对象, 即使 `std::atomic` 的复制构造函数被删除。 - -在C++17之前, 这种初始化因为尝试调用被删除的复制构造函数而失败。 -这个例子其实展示的是C++17改进了直接初始化和复制消除的规则,而不是传统意义上的RVO。