From 94c90ba69a5fdd7c8ff5bf8ade39b2042cdee9a8 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 03:03:53 +0800 Subject: [PATCH 1/9] =?UTF-8?q?mq=E5=8D=A2=E7=91=9F=E7=9A=84homework2-16?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 100 +++++++-------- .../mq\345\215\242\347\221\237.cxx" | 23 ++++ .../mq\345\215\242\347\221\237.cxx" | 27 ++++ .../mq\345\215\242\347\221\237.cxx" | 29 +++++ .../mq\345\215\242\347\221\237.cxx" | 74 +++++++++++ .../mq\345\215\242\347\221\237.md" | 19 +++ .../mq\345\215\242\347\221\237.cxx" | 20 +++ .../mq\345\215\242\347\221\237.cxx" | 18 +++ .../mq\345\215\242\347\221\237.md" | 13 ++ .../mq\345\215\242\347\221\237.cxx" | 56 +++++++++ .../mq\345\215\242\347\221\237.md" | 1 + .../mq\345\215\242\347\221\237.cxx" | 54 ++++++++ .../mq\345\215\242\347\221\237.md" | 3 + .../mq\345\215\242\347\221\237.cxx" | 14 +++ .../mq\345\215\242\347\221\237.cxx" | 119 ++++++++++++++++++ .../mq\345\215\242\347\221\237.cxx" | 17 +++ 16 files changed, 538 insertions(+), 49 deletions(-) create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25402\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25408\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25412\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25415\351\242\230/mq\345\215\242\347\221\237.cxx" create mode 100644 "src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25416\351\242\230/mq\345\215\242\347\221\237.cxx" diff --git a/README.md b/README.md index df0ce97e..085e65b0 100644 --- a/README.md +++ b/README.md @@ -21,74 +21,76 @@ - [前言](#前言) - [`01` 实现管道运算符](#01-实现管道运算符) - + [运行结果](#运行结果) - + [群友提交](#群友提交-0) - + [标准答案](#标准答案-0) - + [解析](#解析-0) + - [运行结果](#运行结果) + - [群友提交](#群友提交) + - [标准答案](#标准答案) + - [解析](#解析) - [`02` 实现自定义字面量 `_f`](#02-实现自定义字面量-_f) - + [运行结果](#运行结果-1) - + [群友提交](#群友提交-1) - + [标准答案](#标准答案-1) - + [解析](#解析-1) + - [运行结果](#运行结果-1) + - [群友提交](#群友提交-1) + - [标准答案](#标准答案-1) + - [解析](#解析-1) - [`03` 实现 `print` 以及特化 `std::formatter`](#03-实现-print-以及特化-stdformatter) - + [运行结果](#运行结果-2) - + [群友提交](#群友提交-2) - + [标准答案](#标准答案-2) - + [解析](#解析-2) + - [运行结果](#运行结果-2) + - [群友提交](#群友提交-2) + - [标准答案](#标准答案-2) + - [解析](#解析-2) - [`04` 给定类模板修改,让其对每一个不同类型实例化有不同 ID](#04-给定类模板修改让其对每一个不同类型实例化有不同-id) - + [运行结果](#运行结果-3) - + [群友提交](#群友提交-3) - + [标准答案](#标准答案-3) + - [运行结果](#运行结果-3) + - [群友提交](#群友提交-3) + - [标准答案](#标准答案-3) - [`05` 实现 `scope_guard` 类型](#05-实现-scope_guard-类型) - + [运行结果](#运行结果-4) - + [群友提交](#群友提交-4) - + [标准答案](#标准答案-4) + - [运行结果](#运行结果-4) + - [群友提交](#群友提交-4) + - [标准答案](#标准答案-4) - [`06` 解释 `std::atomic` 初始化](#06-解释-stdatomic-初始化) - + [群友提交](#群友提交-5) - + [标准答案](#标准答案-5) + - [群友提交](#群友提交-5) + - [标准答案](#标准答案-5) - [`07` `throw new MyException`](#07-throw-new-myexception) - + [运行结果](#运行结果-5) - + [群友提交](#群友提交-6) - + [标准答案](#标准答案-6) + - [运行结果](#运行结果-5) + - [群友提交](#群友提交-6) + - [标准答案](#标准答案-6) - [`08` 定义`array`推导指引](#08-定义array推导指引) - + [运行结果](#运行结果-6) - + [群友提交](#群友提交-7) - + [标准答案](#标准答案-7) + - [运行结果](#运行结果-6) + - [群友提交](#群友提交-7) + - [标准答案](#标准答案-7) - [`09` 名字查找的问题](#09-名字查找的问题) - + [运行结果](#运行结果-7) - + [群友提交](#群友提交-8) - + [标准答案](#标准答案-8) + - [运行结果](#运行结果-7) + - [群友提交](#群友提交-8) + - [标准答案](#标准答案-8) - [`10` 遍历任意类数据成员](#10-遍历任意类数据成员) - + [运行结果](#运行结果-8) - + [群友提交](#群友提交-9) - + [标准答案](#标准答案-9) + - [运行结果](#运行结果-8) + - [群友提交](#群友提交-9) + - [标准答案](#标准答案-9) - [`C++17` 写法](#c17-写法) - [`C++20` 写法](#c20-写法) - + [补充说明](#补充说明-0) + - [无法处理引用类型以及不可移动类型](#无法处理引用类型以及不可移动类型) + - [补充说明](#补充说明) - [`11` `emplace_back()` 的问题](#11-emplace_back-的问题) - + [群友提交](#群友提交-10) - + [标准答案](#标准答案-10) + - [群友提交](#群友提交-10) + - [标准答案](#标准答案-10) - [`12` 实现`make_vector()`](#12-实现make_vector) - + [运行结果](#运行结果-9) - + [群友提交](#群友提交-11) - + [标准答案](#标准答案-11) + - [运行结果](#运行结果-9) + - [群友提交](#群友提交-11) + - [标准答案](#标准答案-11) - [运行结果](#运行结果-10) - [`13` 关于 `return std::move`](#13-关于-return-stdmove) - + [群友提交](#群友提交-12) - + [标准答案](#标准答案-12) + - [群友提交](#群友提交-12) + - [标准答案](#标准答案-12) - [`14` 以特殊方法修改命名空间中声明的对象](#14-以特殊方法修改命名空间中声明的对象) - + [运行结果](#运行结果-11) - + [群友提交](#群友提交-13) - + [标准答案](#标准答案-13) + - [运行结果](#运行结果-11) + - [群友提交](#群友提交-13) + - [标准答案](#标准答案-13) - [利用符号来解决](#利用符号来解决) - [直接修改内存](#直接修改内存) - [利用名字查找规则](#利用名字查找规则) - [`15` 表达式模板](#15-表达式模板) - + [群友提交](#群友提交-14) - + [标准答案](#标准答案-14) -- [`16` 通透函数宏](#16-制造传递函数模板的宏) - + [群友提交](#群友提交-15) - + [标准答案](#标准答案-15) + - [运行结果](#运行结果-12) + - [群友提交](#群友提交-14) + - [标准答案](#标准答案-14) +- [`16` 制造传递函数模板的宏](#16-制造传递函数模板的宏) + - [群友提交](#群友提交-15) + - [标准答案](#标准答案-15) @@ -439,7 +441,7 @@ impl::Helper operator""_f(const char* s, std::size_t len) noexcept { } ``` -`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `mpl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_veiw` 作为数据成员,存储了格式字符串,以供后面格式化使用。 +`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `impl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_view` 作为数据成员,存储了格式字符串,以供后面格式化使用。 **重点只在于 `operator()`。** 它是一个变参模板,用来接取我们传入的任意类型和个数的参数,然后返回格式化后的字符串。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25402\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25402\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..974cbb73 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25402\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,23 @@ +#include +#include +#include + +constexpr auto operator""_f(const char* str, size_t) +{ + return [=](T&& ...args) + { + return std::vformat(str, std::make_format_args(std::forward(args)...)); + }; +} + +int main() { + + std::cout << "乐 :{} *\n"_f(5); + std::cout << "乐 :{0} {0} *\n"_f(5); + std::cout << "乐 :{:b} *\n"_f(0b01010101); + std::cout << "{:*<10}"_f("卢瑟"); + std::cout << '\n'; + int n{}; + std::cin >> n; + std::cout << "π:{:.{}f}\n"_f(std::numbers::pi_v, n); +} diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..73652752 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,27 @@ +#include +#include + +struct Frac { + int a, b; +}; + +template +void print(std::string_view format_str, Args const&... args) { + std::cout << std::vformat(format_str, std::make_format_args(std::forward(args)...)); +} + +namespace std { + template<> + struct formatter : formatter { + auto format(Frac const& f, format_context& ctx) const { + return format_to(ctx.out(), "{}/{}", f.a, f.b); + } + }; +} + +int main() { + const Frac f{ 1, 10 }; + print("{}", f); + + return 0; +} diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..0b5d617a --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25404\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,29 @@ +#include +class ComponentBase { +protected: + static inline std::size_t component_type_count = 0; +}; +template +class Component : public ComponentBase { +public: + static std::size_t component_type_id() { + static std::size_t id = component_type_count++; + return 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/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..633787b8 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25405\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,74 @@ +#include +#include +#include + + +template + requires requires(F f, Args...args) { std::invoke(f, args...); } +struct scope_guard { + F f; + std::tuplevalues; + + scope_guard(auto&& func, auto&&...args) :f{ std::forward(func) }, values{ std::forward(args)... } {} + ~scope_guard() { + std::apply(f, values); + } + scope_guard(const scope_guard&) = delete; +}; + +template//推导指引非常重要 +scope_guard(F&&, Args&&...) -> scope_guard, std::decay_t...>; +struct X { + X() { puts("X()"); } + X(const X&) { puts("X(const X&)"); } + X(X&&) noexcept { puts("X(X&&)"); } + ~X() { puts("~X()"); } +}; + +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/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" new file mode 100644 index 00000000..161c89a6 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -0,0 +1,19 @@ +`std::atomic n = 6` 中,由于 `6` 和 `std::atomic` 不是同一类型(但是这里其实有一个用户定义转换序列,你可以简单的认为 `6` 可以隐式转换)。 + +即调用转换构造函数: + +```cpp +constexpr atomic( T desired ) noexcept; +``` + +`6` 会调用转换构造函数,构造出一个临时 `atomic` 对象用来**复制初始化** `n`,即: + +```cpp +std::atomic n = std::atomic(6); +``` + +根据复制消除的规则:当初始化式是纯右值时,C++17 前通常会优化掉,C++17 起始终不会进行对移动构造函数的调用。 + +因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 + +然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..61a66bfa --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,20 @@ +#include + +struct MyException :std::exception { + const char* data{}; + MyException(const char* s) :data(s) { puts("MyException()"); } + ~MyException() { puts("~MyException()"); } + const char* what()const noexcept { return data; } +}; +void f2() { + throw new MyException("new Exception异常...."); +} +int main() { + try { + f2(); + } + catch (std::exception *e) + { + std::cout << std::unique_ptr(e)->what() << '\n'; + } +} diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25408\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25408\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..823e34d1 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25408\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,18 @@ +#include +template +struct array { + Ty* begin() { return arr; }; + Ty* end() { return arr + size; }; + Ty arr[size]; +}; + +template + requires (std::is_same_v&&...) +array(Ty, Args...)->array; + +int main() { + ::array arr{ 1, 2, 3, 4, 5 }; + for (const auto& i : arr) { + std::cout << i << ' '; + } +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" new file mode 100644 index 00000000..7ec9f3c5 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -0,0 +1,13 @@ +**已知:** + +> 对于在模板的定义中所使用的非待决名,当检查该模板的定义时将进行无限定的名字查找。在这个位置与声明之间的绑定并不会受到在实例化点可见的声明的影响。 而对于在模板定义中所使用的待决名,它的查找会推迟到得知它的模板实参之时。 此时,ADL 将同时在模板的定义语境和在模板的实例化语境中检查可见的具有外部连接的(C++11 前)函数声明,而非 ADL 的查找只会检查在模板的定义语境中可见的具有外部连接的(C++11 前)函数声明。 (换句话说,在模板定义之后添加新的函数声明,除非通过 ADL 否则仍是不可见的。) 如果在 ADL 查找所检查的命名空间中,在某个别的翻译单元中声明了一个具有外部连接的更好的匹配声明,或者如果当同样检查这些翻译单元时其查找会导致歧义,那么行为未定义。 无论哪种情况,如果某个基类取决于某个模板形参,那么无限定名字查找不会检查它的作用域(在定义点和实例化点都不会)。 + +这里的最后一句话比较迷惑:**无论哪种情况,如果某个基类取决于某个模板形参,那么无限定名字查找不会检查它的作用域(在定义点和实例化点都不会)。** + +因为 `this->f()` 也是无限定的。但这里确实查找到了基类的 `f()` 函数。对此 *mq 白* 给出的解释是:因为 `f` 是待决名,查找会推迟到得知它模板实参之时,此时父类不再取决于模板形参,已经实例化了,就没有上面说的那个问题了。 + +**因此:** + +`t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 + +`t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `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\25410\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..53c97d52 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,56 @@ +#include +#include + +struct Anyth { + template + operator T(); +}; + +template +consteval size_t size(Args&&... args) +{ + static_assert(std::is_aggregate_v); + if constexpr (!requires{T{ args... }; }) + { + return sizeof...(args) - 1; + } + else + { + return size(args..., Anyth{}); + } +} + +template +void for_each_member(T const& v, F&& f) { + static_assert(std::is_aggregate_v); + + if constexpr (size() == 4u) { + const auto& [m0, m1, m2, m3] = v; + f(m0); f(m1); f(m2); f(m3); + } + else if constexpr (size() == 3u) { + const auto& [m0, m1, m2] = v; + f(m0); f(m1); f(m2); + } + else if constexpr (size() == 2u) { + const auto& [m0, m1] = v; + f(m0); f(m1); + } + else if constexpr (size() == 1u) { + const auto& [m0] = v; + f(m0); + } +} + +int main() { + struct X { std::string s{ " " }; }x; + struct Y { double a{}, b{}, c{}, d{}; }y; + std::cout << size() << '\n'; + std::cout << size() << '\n'; + + auto print = [](const auto& member) { + std::cout << member << ' '; + }; + for_each_member(x, print); + for_each_member(y, print); +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" new file mode 100644 index 00000000..faf93095 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -0,0 +1 @@ +C++20 前不允许使用 `()` 初始化聚合体。 \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25412\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25412\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..6d945619 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25412\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,54 @@ +#include +#include + +inline void dbg(const char* msg) +{ + std::puts(msg); + std::fflush(stdout); +} + +struct X { + X() noexcept + { + dbg("X()"); + }; + + ~X() noexcept + { + dbg("~X()"); + }; + + X(const X&) + { + dbg("X(const X&)"); + } + + X(X&&) noexcept + { + dbg("X(X&&)"); + } +}; + +constexpr auto make_vector(auto&& ...args) { return std::vector{ {std::forward(args)...} }; } + +void test() +{ + static_assert(requires { + { + make_vector(std::vector{ 1, 2, 3 }) + } -> std::same_as>>; + { + make_vector(1, 2, 3) + } -> std::same_as>; + make_vector(1, 2, 3).size() == 3; + }); + X x1; + X x2; + auto vec = make_vector(x1, std::move(x2)); +} + +int main() +{ + test(); + dbg("test end"); +} diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" new file mode 100644 index 00000000..ee1fa440 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -0,0 +1,3 @@ +1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 +2. 有问题,悬垂引用。 +3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..d444609f --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,14 @@ +#include + +extern "C"{ + namespace ss { + int a = 0; + } +} + +extern "C" int a; + +int main() { + a = 100; + std::cout << ss::a << '\n'; +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25415\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25415\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..15fe8c1d --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25415\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include + +// 为std::vector增加一个自定义的赋值函数 +template + requires std::disjunction_v, std::is_floating_point> +class vector : public std::vector { +public: + using std::vector::vector; + using std::vector::size; + using std::vector::operator[]; + template + vector& operator=(const E& e) + { + const auto count = std::min(size(), e.size()); + this->resize(count); + for (std::size_t idx { 0 }; idx < count; ++idx) { + this->operator[](idx) = e[idx]; + } + return *this; + } +}; + +// 表达式模板类 +template +class vector_expr { + const Lhs& lhs; + const Rhs& rhs; + +public: + vector_expr(const Lhs& l, const Rhs& r) : lhs(l), rhs(r) {} + + auto operator[](std::size_t idx) const { + return Op::apply(lhs[idx], rhs[idx]); + } + + std::size_t size() const { + return std::min(lhs.size(), rhs.size()); + } +}; + +// 运算符重载 +struct Add { + template + static T apply(const T& lhs, const T& rhs) { + return lhs + rhs; + } +}; + +struct Subtract { + template + static T apply(const T& lhs, const T& rhs) { + return lhs - rhs; + } +}; + +struct Multiply { + template + static T apply(const T& lhs, const T& rhs) { + return lhs * rhs; + } +}; + +struct Divide { + template + static T apply(const T& lhs, const T& rhs) { + return lhs / rhs; + } +}; + +template +auto operator+(const Lhs& lhs, const Rhs& rhs) { + return vector_expr(lhs, rhs); +} + +template +auto operator-(const Lhs& lhs, const Rhs& rhs) { + return vector_expr(lhs, rhs); +} + +template +auto operator*(const Lhs& lhs, const Rhs& rhs) { + return vector_expr(lhs, rhs); +} + +template +auto operator/(const Lhs& lhs, const Rhs& rhs) { + return vector_expr(lhs, rhs); +} + +int main() +{ + auto print = [](const auto& v) { + std::ranges::copy(v, std::ostream_iterator> { std::cout, ", " }); + std::cout << std::endl; + }; + const vector a { 1.2764, 1.3536, 1.2806, 1.9124, 1.8871, 1.7455 }; + const vector b { 2.1258, 2.9679, 2.7635, 2.3796, 2.4820, 2.4195 }; + const vector c { 3.9064, 3.7327, 3.4760, 3.5705, 3.8394, 3.8993 }; + const vector d { 4.7337, 4.5371, 4.5517, 4.2110, 4.6760, 4.3139 }; + const vector e { 5.2126, 5.1452, 5.8678, 5.1879, 5.8816, 5.6282 }; + + { + vector result(6); + for (std::size_t idx = 0; idx < 6; idx++) { + result[idx] = a[idx] - b[idx] * c[idx] / d[idx] + e[idx]; + } + print(result); + } + { + vector result(6); + result = a - b * c / d + e; // 使用表达式模板计算 + print(result); + } + return 0; +} \ No newline at end of file diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25416\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25416\351\242\230/mq\345\215\242\347\221\237.cxx" new file mode 100644 index 00000000..b27c4a99 --- /dev/null +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25416\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -0,0 +1,17 @@ +#include + +#define BY_NAME(func) \ +[](auto&&... args) \ +{ \ + return func(std::forward(args)...); \ +} + +template +auto foo(F f, Args&&...args) { + return f(std::forward(args)...); +} + +int main() { + const auto result = foo(BY_NAME(std::min), 2, 3); + std::cout << result << '\n'; +} \ No newline at end of file From d0b4551bd65fafc864b65269e22853fc04bfc7f9 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 11:46:45 +0800 Subject: [PATCH 2/9] =?UTF-8?q?md=E6=96=87=E4=BB=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=A9=BA=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" | 2 +- .../\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" | 2 +- .../\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" | 2 +- .../\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" index 161c89a6..8d295ad0 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -16,4 +16,4 @@ std::atomic n = std::atomic(6); 因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 -然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 \ No newline at end of file +然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" index 7ec9f3c5..efc2a82a 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -10,4 +10,4 @@ `t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 -`t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 \ No newline at end of file +`t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" index faf93095..a53b21fa 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -1 +1 @@ -C++20 前不允许使用 `()` 初始化聚合体。 \ No newline at end of file +C++20 前不允许使用 `()` 初始化聚合体。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" index ee1fa440..3dbc6abb 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,3 +1,3 @@ 1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 2. 有问题,悬垂引用。 -3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 \ No newline at end of file +3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 From 1e54d63dc99ee139bf2c413920b792876fd185b8 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 11:56:08 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E6=9B=B4=E6=AD=A3=E7=AC=AC=E4=B8=83?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" | 1 + 1 file changed, 1 insertion(+) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" index 61a66bfa..dc470194 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25407\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -1,4 +1,5 @@ #include +#include struct MyException :std::exception { const char* data{}; From 5262246dadd0a45e7b6907227a85f523fc5e2283 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 12:35:11 +0800 Subject: [PATCH 4/9] =?UTF-8?q?md=E6=96=87=E4=BB=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=A9=BA=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" | 1 + 4 files changed, 4 insertions(+) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" index 8d295ad0..e1921143 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -17,3 +17,4 @@ std::atomic n = std::atomic(6); 因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" index efc2a82a..c92b9ccb 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -11,3 +11,4 @@ `t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 `t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" index a53b21fa..3c6f7782 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -1 +1,2 @@ C++20 前不允许使用 `()` 初始化聚合体。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" index 3dbc6abb..3cf57f90 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,3 +1,4 @@ 1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 2. 有问题,悬垂引用。 3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 + From 8b13c30b455a7b73b77fe3275e28360ac3324c8d Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 12:42:20 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E8=A7=84=E8=8C=83md=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" | 1 - .../\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" | 1 - .../\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" | 1 - .../\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" | 1 - 4 files changed, 4 deletions(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" index e1921143..8d295ad0 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -17,4 +17,3 @@ std::atomic n = std::atomic(6); 因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" index c92b9ccb..efc2a82a 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -11,4 +11,3 @@ `t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 `t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" index 3c6f7782..a53b21fa 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,2 +1 @@ C++20 前不允许使用 `()` 初始化聚合体。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" index 3cf57f90..3dbc6abb 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,4 +1,3 @@ 1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 2. 有问题,悬垂引用。 3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 - From 8aa7d02c0cf8fa1d03a084d94afe36547e62dc1f Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 12:49:41 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E8=A7=84=E8=8C=83md=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" | 1 + .../\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 085e65b0..00032451 100644 --- a/README.md +++ b/README.md @@ -441,7 +441,7 @@ impl::Helper operator""_f(const char* s, std::size_t len) noexcept { } ``` -`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `impl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_view` 作为数据成员,存储了格式字符串,以供后面格式化使用。 +`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `mpl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_veiw` 作为数据成员,存储了格式字符串,以供后面格式化使用。 **重点只在于 `operator()`。** 它是一个变参模板,用来接取我们传入的任意类型和个数的参数,然后返回格式化后的字符串。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" index 8d295ad0..e1921143 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -17,3 +17,4 @@ std::atomic n = std::atomic(6); 因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" index efc2a82a..c92b9ccb 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -11,3 +11,4 @@ `t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 `t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" index a53b21fa..3c6f7782 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -1 +1,2 @@ C++20 前不允许使用 `()` 初始化聚合体。 + diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" index 3dbc6abb..3cf57f90 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,3 +1,4 @@ 1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 2. 有问题,悬垂引用。 3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 + From 26a3cd62714870431b010815e029c5a867b47508 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 13:17:23 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E8=A7=84=E8=8C=83=E5=92=8C=E6=9B=B4?= =?UTF-8?q?=E6=94=B9md=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 100 +++++++++--------- .../mq\345\215\242\347\221\237.cxx" | 14 ++- .../mq\345\215\242\347\221\237.md" | 1 - .../mq\345\215\242\347\221\237.md" | 1 - .../mq\345\215\242\347\221\237.md" | 1 - .../mq\345\215\242\347\221\237.md" | 1 - 6 files changed, 55 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index 00032451..f14003f7 100644 --- a/README.md +++ b/README.md @@ -21,76 +21,74 @@ - [前言](#前言) - [`01` 实现管道运算符](#01-实现管道运算符) - - [运行结果](#运行结果) - - [群友提交](#群友提交) - - [标准答案](#标准答案) - - [解析](#解析) + + [运行结果](#运行结果) + + [群友提交](#群友提交-0) + + [标准答案](#标准答案-0) + + [解析](#解析-0) - [`02` 实现自定义字面量 `_f`](#02-实现自定义字面量-_f) - - [运行结果](#运行结果-1) - - [群友提交](#群友提交-1) - - [标准答案](#标准答案-1) - - [解析](#解析-1) + + [运行结果](#运行结果-1) + + [群友提交](#群友提交-1) + + [标准答案](#标准答案-1) + + [解析](#解析-1) - [`03` 实现 `print` 以及特化 `std::formatter`](#03-实现-print-以及特化-stdformatter) - - [运行结果](#运行结果-2) - - [群友提交](#群友提交-2) - - [标准答案](#标准答案-2) - - [解析](#解析-2) + + [运行结果](#运行结果-2) + + [群友提交](#群友提交-2) + + [标准答案](#标准答案-2) + + [解析](#解析-2) - [`04` 给定类模板修改,让其对每一个不同类型实例化有不同 ID](#04-给定类模板修改让其对每一个不同类型实例化有不同-id) - - [运行结果](#运行结果-3) - - [群友提交](#群友提交-3) - - [标准答案](#标准答案-3) + + [运行结果](#运行结果-3) + + [群友提交](#群友提交-3) + + [标准答案](#标准答案-3) - [`05` 实现 `scope_guard` 类型](#05-实现-scope_guard-类型) - - [运行结果](#运行结果-4) - - [群友提交](#群友提交-4) - - [标准答案](#标准答案-4) + + [运行结果](#运行结果-4) + + [群友提交](#群友提交-4) + + [标准答案](#标准答案-4) - [`06` 解释 `std::atomic` 初始化](#06-解释-stdatomic-初始化) - - [群友提交](#群友提交-5) - - [标准答案](#标准答案-5) + + [群友提交](#群友提交-5) + + [标准答案](#标准答案-5) - [`07` `throw new MyException`](#07-throw-new-myexception) - - [运行结果](#运行结果-5) - - [群友提交](#群友提交-6) - - [标准答案](#标准答案-6) + + [运行结果](#运行结果-5) + + [群友提交](#群友提交-6) + + [标准答案](#标准答案-6) - [`08` 定义`array`推导指引](#08-定义array推导指引) - - [运行结果](#运行结果-6) - - [群友提交](#群友提交-7) - - [标准答案](#标准答案-7) + + [运行结果](#运行结果-6) + + [群友提交](#群友提交-7) + + [标准答案](#标准答案-7) - [`09` 名字查找的问题](#09-名字查找的问题) - - [运行结果](#运行结果-7) - - [群友提交](#群友提交-8) - - [标准答案](#标准答案-8) + + [运行结果](#运行结果-7) + + [群友提交](#群友提交-8) + + [标准答案](#标准答案-8) - [`10` 遍历任意类数据成员](#10-遍历任意类数据成员) - - [运行结果](#运行结果-8) - - [群友提交](#群友提交-9) - - [标准答案](#标准答案-9) + + [运行结果](#运行结果-8) + + [群友提交](#群友提交-9) + + [标准答案](#标准答案-9) - [`C++17` 写法](#c17-写法) - [`C++20` 写法](#c20-写法) - - [无法处理引用类型以及不可移动类型](#无法处理引用类型以及不可移动类型) - - [补充说明](#补充说明) + + [补充说明](#补充说明-0) - [`11` `emplace_back()` 的问题](#11-emplace_back-的问题) - - [群友提交](#群友提交-10) - - [标准答案](#标准答案-10) + + [群友提交](#群友提交-10) + + [标准答案](#标准答案-10) - [`12` 实现`make_vector()`](#12-实现make_vector) - - [运行结果](#运行结果-9) - - [群友提交](#群友提交-11) - - [标准答案](#标准答案-11) + + [运行结果](#运行结果-9) + + [群友提交](#群友提交-11) + + [标准答案](#标准答案-11) - [运行结果](#运行结果-10) - [`13` 关于 `return std::move`](#13-关于-return-stdmove) - - [群友提交](#群友提交-12) - - [标准答案](#标准答案-12) + + [群友提交](#群友提交-12) + + [标准答案](#标准答案-12) - [`14` 以特殊方法修改命名空间中声明的对象](#14-以特殊方法修改命名空间中声明的对象) - - [运行结果](#运行结果-11) - - [群友提交](#群友提交-13) - - [标准答案](#标准答案-13) + + [运行结果](#运行结果-11) + + [群友提交](#群友提交-13) + + [标准答案](#标准答案-13) - [利用符号来解决](#利用符号来解决) - [直接修改内存](#直接修改内存) - [利用名字查找规则](#利用名字查找规则) - [`15` 表达式模板](#15-表达式模板) - - [运行结果](#运行结果-12) - - [群友提交](#群友提交-14) - - [标准答案](#标准答案-14) -- [`16` 制造传递函数模板的宏](#16-制造传递函数模板的宏) - - [群友提交](#群友提交-15) - - [标准答案](#标准答案-15) + + [群友提交](#群友提交-14) + + [标准答案](#标准答案-14) +- [`16` 通透函数宏](#16-制造传递函数模板的宏) + + [群友提交](#群友提交-15) + + [标准答案](#标准答案-15) @@ -441,7 +439,7 @@ impl::Helper operator""_f(const char* s, std::size_t len) noexcept { } ``` -`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `mpl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_veiw` 作为数据成员,存储了格式字符串,以供后面格式化使用。 +`operator""_f` 本身非常简单,只是用来把传入的参数(格式字符串)和长度,构造 `impl::Helper` 对象再返回。`Helper` 类型使用了一个 `string_view` 作为数据成员,存储了格式字符串,以供后面格式化使用。 **重点只在于 `operator()`。** 它是一个变参模板,用来接取我们传入的任意类型和个数的参数,然后返回格式化后的字符串。 diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" index 73652752..56ee6275 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -10,14 +10,12 @@ void print(std::string_view format_str, Args const&... args) { std::cout << std::vformat(format_str, std::make_format_args(std::forward(args)...)); } -namespace std { - template<> - struct formatter : formatter { - auto format(Frac const& f, format_context& ctx) const { - return format_to(ctx.out(), "{}/{}", f.a, f.b); - } - }; -} +template<> +struct std::formatter : std::formatter { + auto format(Frac const& f, format_context& ctx) const { + return std::format_to(ctx.out(), "{}/{}", f.a, f.b); + } +}; int main() { const Frac f{ 1, 10 }; diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" index e1921143..8d295ad0 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25406\351\242\230/mq\345\215\242\347\221\237.md" @@ -17,4 +17,3 @@ std::atomic n = std::atomic(6); 因此在 C++17 之前的版本,理所应当应该查找检测复制/移动 构造函数,满足要求才可以通过编译。但是实际上 `atomic` 的复制构造被删除(因为三/五/零法则,移动构造也被抑制生成)了,所以自然而然地不允许。 然而在 C++17 起,复制消除变为强制要求。纯右值表达式作为构造对象的参数,不会再调用移动构造,也不会去检测,而是原位构造。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" index c92b9ccb..efc2a82a 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25409\351\242\230/mq\345\215\242\347\221\237.md" @@ -11,4 +11,3 @@ `t()` 中的 `this->f()` 是无限定的待决调用,会在明确它的模板实参之时再次进行关于 `f` 的名字查找,并且会查找基类,因此找到了基类的成员函数 `f()`。 `t2()` 中的 `f()` 是无限定的非待决调用,检查该模板的定义时将进行关于 `f` 的无限定的名字查找(无法查找父类的定义),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" index 3c6f7782..a53b21fa 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25411\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,2 +1 @@ C++20 前不允许使用 `()` 初始化聚合体。 - diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" index 3cf57f90..3dbc6abb 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25413\351\242\230/mq\345\215\242\347\221\237.md" @@ -1,4 +1,3 @@ 1. `std::move()` 个 jb 啊,不 move 也能复制消除,move 还可能影响优化。 2. 有问题,悬垂引用。 3. 没有问题,类数据成员不是隐式可移动实体,需要通过 `std::move` 让重载决议选择移动构造。 - From 946d70fbee6aab88b098704ae04d65056ea30f41 Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 13:33:19 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E7=AC=AC=E4=B8=89=E9=A2=98=E7=AD=94?= =?UTF-8?q?=E6=A1=88=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" index 56ee6275..430e5c26 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25403\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -12,7 +12,7 @@ void print(std::string_view format_str, Args const&... args) { template<> struct std::formatter : std::formatter { - auto format(Frac const& f, format_context& ctx) const { + auto format(Frac const& f, auto& ctx) const { return std::format_to(ctx.out(), "{}/{}", f.a, f.b); } }; From 5274130f5a74bb653955100a8630dcd62e9b0b3e Mon Sep 17 00:00:00 2001 From: LeeZQXML <2919625053@qq.com> Date: Thu, 29 Feb 2024 13:38:22 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E7=AC=AC=E5=8D=81=E5=9B=9B=E9=A2=98?= =?UTF-8?q?=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" | 1 + 1 file changed, 1 insertion(+) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" index d444609f..390f4b92 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25414\351\242\230/mq\345\215\242\347\221\237.cxx" @@ -1,3 +1,4 @@ +//!msvc #include extern "C"{