Skip to content

Commit

Permalink
补完第九题之前的提交,第九题就不要了
Browse files Browse the repository at this point in the history
  • Loading branch information
loser-linker committed Aug 16, 2023
1 parent fa4c124 commit 10609d3
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
83 changes: 83 additions & 0 deletions src/群友提交/第五题/loser_linker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include <concepts>
#include <cstdio>
#include <functional>
#include <iostream>

template<typename F,typename... Ts>
concept callable = requires(F&& f,Ts&&... ts){
std::invoke(f,ts...);
};

template <class Func, class... Args>
requires callable<Func,Args...>
class scope_guard {
Func func_;
std::tuple<Args...> args_;
public:
template<typename F,typename... Ts>
scope_guard(F&& func, Ts&&... args)
: func_{ std::forward<Func>(func) }
, args_{ std::forward<Ts>(args)... }
{
}

~scope_guard()
{
std::apply(func_, args_);
}

scope_guard(scope_guard const &) = delete;
scope_guard& operator=(scope_guard const &) = delete;
};

template <class F, class... Ts>
scope_guard(F&&, Ts&&...) -> scope_guard<std::decay_t<F>, std::decay_t<Ts>...>;

struct X {
X(){ puts("X()"); }

X(const X&){ puts("X(const X&)"); }

X(X&&) noexcept{ puts("X(X&&)"); }

~X(){ puts("~X()"); }
};

int main()
{
{
auto x = new X{};
auto guard = scope_guard([&] {
delete x;
x = nullptr;
});
}
puts("----------");
{
struct Test {
void operator()(X*& x)
{
delete x;
x = nullptr;
}
};

auto x = new X{};
Test t;
auto guard = scope_guard(t, x);
}
puts("----------");
{
struct Test {
void f(X*& x)
{
delete x;
x = nullptr;
}
};

auto x = new X{};
Test t;
auto guard = scope_guard{&Test::f, &t, x}; // error
}
}
6 changes: 6 additions & 0 deletions src/群友提交/第六题/loser_linker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
6能转换为std::atomic<int>,
是因为调用了`constexpr atomic(T) noexcept;`用户自定义转换构造函数,
相当于`std::atomic<int> n = std::atomic<int>(6);`
在c++17之前的版本,通过调用复制或移动构造函数来完成n的初始化,
标准规定std::atomic既不可复制亦不可移动,所以编译失败。
c++17标准以后,复制清除变成强制要求,与此同时,用右值初始化对象不会再调用移动构造,而是直接原位构造,所以通过编译。

0 comments on commit 10609d3

Please sign in to comment.