Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f3f03ce

Browse files
committed
1. 补充 std::thread 源码解析中构造函数的约束
2. 修改第二章失效的 libc++ 超链接
1 parent cfa137e commit f3f03ce

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

‎md/02使用线程.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,7 @@ thread _Impl;
889889
stop_source _Ssource;
890890
```
891891
892-
[MSVC STL](https://github.com/microsoft/STL/blob/23344e2/stl/inc/thread#L435-L436)[libstdc++](https://github.com/gcc-mirror/gcc/blob/1a5e4dd/libstdc%2B%2B-v3/include/std/thread#L290-L291)[libc++](https://github.com/llvm/llvm-project/blob/7162fd7/libcxx/include/__thread/jthread.h#L125-L126) 均是如此。
892+
[MSVC STL](https://github.com/microsoft/STL/blob/23344e2/stl/inc/thread#L435-L436)[libstdc++](https://github.com/gcc-mirror/gcc/blob/1a5e4dd/libstdc%2B%2B-v3/include/std/thread#L290-L291)[libc++](https://github.com/llvm/llvm-project/blob/04f01a2/libcxx/include/__thread/jthread.h#L124-L125) 均是如此。
893893
894894
`stop_source` 通常占 8 字节,先前 `std::thread` 源码解析详细聊过其不同标准库对其保有的成员不同,简单来说也就是 64 位环境,大小为 16 或者 8。也就是 `sizeof(std::jthread)` 的值相比 `std::thread` 会多 8 ,为 `24``16`
895895

‎md/详细分析/01thread的构造与源码解析.md‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,37 @@ struct _Thrd_t { // thread identifier for Win32
6868
6969
前三个构造函数都没啥要特别聊的,非常简单,只有第四个构造函数较为复杂,且是我们本章重点,需要详细讲解。(*注意 MSVC 使用标准库的内容很多时候不加 **std::**,脑补一下就行*)
7070
71-
如你所见,这个构造函数本身并没有做什么,它只是一个可变参数成员函数模板,增加了一些 [SFINAE](https://zh.cppreference.com/w/cpp/language/sfinae) 进行约束我们传入的[可调用](https://zh.cppreference.com/w/cpp/named_req/Callable)对象的类型不能是 `std::thread`。函数体中调用了一个函数 [**`_Start`**](https://github.com/microsoft/STL/blob/8e2d724cc1072b4052b14d8c5f81a830b8f1d8cb/stl/inc/thread#L72-L87),将我们构造函数的参数全部完美转发,去调用它,这个函数才是我们的重点,如下:
71+
如你所见,这个构造函数本身并没有做什么,它只是一个可变参数成员函数模板,增加了一些 [SFINAE](https://zh.cppreference.com/w/cpp/language/sfinae) 进行约束我们传入的[可调用](https://zh.cppreference.com/w/cpp/named_req/Callable)对象的类型不能是 `std::thread`。关于这个约束你可能有问题,因为 `std::thread` 他并没有 `operator()` 的重载,不是可调用类型,这个 `enable_if_t` 的意义是什么呢?其实很简单,如下:
72+
73+
```cpp
74+
struct X{
75+
X(X&& x)noexcept{}
76+
template <class Fn, class... Args>
77+
X(Fn&& f,Args&&...args){}
78+
X(const X&) = delete;
79+
};
80+
81+
X x{ [] {} };
82+
X x2{ x }; // 选择到了有参构造函数,不导致编译错误
83+
```
84+
85+
以上这段代码可以正常的[通过编译](https://godbolt.org/z/6zhW6xjqP)。这是重载决议的事情,我们知道,`std::thread` 是不可复制的,这种代码自然不应该让它通过编译,选择到我们的有参构造,所以我们添加一个约束让其不能选择到我们的有参构造:
86+
87+
```cpp
88+
template <class Fn, class... Args, std::enable_if_t<!std::is_same_v<std::remove_cvref_t<Fn>, X>, int> = 0>
89+
```
90+
91+
这样,这段代码就会正常的出现[编译错误](https://godbolt.org/z/Mc1h1GcdT),信息如下:
92+
93+
```txt
94+
error C2280: "X::X(const X &)": 尝试引用已删除的函数
95+
note: 参见"X::X"的声明
96+
note: "X::X(const X &)": 已隐式删除函数
97+
```
98+
99+
也就满足了我们的要求,重载决议选择到了弃置复制构造函数产生编译错误,这也就是源码中添加约束的目的。
100+
101+
而构造函数体中调用了一个函数 [**`_Start`**](https://github.com/microsoft/STL/blob/8e2d724cc1072b4052b14d8c5f81a830b8f1d8cb/stl/inc/thread#L72-L87),将我们构造函数的参数全部完美转发,去调用它,这个函数才是我们的重点,如下:
72102

73103
```cpp
74104
template <class _Fn, class... _Args>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /