forked from Mq-b/Loser-HomeWork
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fa4c124
commit 10609d3
Showing
2 changed files
with
89 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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标准以后,复制清除变成强制要求,与此同时,用右值初始化对象不会再调用移动构造,而是直接原位构造,所以通过编译。 |