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..9f6db136 --- /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), std::forward(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