@@ -395,16 +395,16 @@ void f(){
395
395
396
396
### 传递参数
397
397
398
- 向可调用对象或函数传递参数很简单 ,我们前面也都写了,只需要将这些参数作为 ` std::thread ` 的构造参数即可。需要注意的是,这些参数会复制到新线程的内存空间中,即使函数中的参数是引用,依然** 实际是复制** 。
398
+ 向可调用对象传递参数很简单 ,我们前面也都写了,只需要将这些参数作为 ` std::thread ` 的构造参数即可。需要注意的是,这些参数会复制到新线程的内存空间中,即使函数中的参数是引用,依然** 实际是复制** 。
399
399
400
400
``` cpp
401
401
void f (int, const int& a);
402
402
403
403
int n = 1;
404
- std::thread t( f, 3, n) ;
404
+ std::thread t{ f, 3, n } ;
405
405
```
406
406
407
- 线程对象 t 的构造没有问题,可以通过编译,但是这个 n 实际上并没有按引用传递,而按值复制的 。我们可以打印地址来验证我们的猜想。
407
+ 线程对象 t 的构造没有问题,可以通过编译,但是这个 n 实际上并没有按引用传递,而是按值复制的 。我们可以打印地址来验证我们的猜想。
408
408
409
409
```cpp
410
410
void f(int, const int& a) { // a 并非引用了局部对象 n
@@ -414,12 +414,12 @@ void f(int, const int& a) { // a 并非引用了局部对象 n
414
414
int main() {
415
415
int n = 1;
416
416
std::cout << &n << '\n';
417
- std::thread t( f, 3, n) ;
417
+ std::thread t{ f, 3, n } ;
418
418
t.join();
419
419
}
420
420
```
421
421
422
- [ 运行代码] ( https://godbolt.org/z/TzWeW5rxh ) ,打印的地址截然不同。
422
+ [ 运行代码] ( https://godbolt.org/z/YPhbWbxYn ) ,打印的地址截然不同。
423
423
424
424
可以通过编译,但通常这不符合我们的需求,因为我们的函数中的参数是引用,我们自然希望能引用调用方传递的参数,而不是复制。如果我们的 f 的形参类型不是 ** const 的引用** ,则会产生一个[ 编译错误] ( https://godbolt.org/z/3nMb4asnG ) 。
425
425
@@ -433,12 +433,12 @@ void f(int, int& a) {
433
433
int main() {
434
434
int n = 1;
435
435
std::cout << &n << '\n';
436
- std::thread t( f, 3, std::ref(n)) ;
436
+ std::thread t { f, 3, std::ref(n) } ;
437
437
t.join();
438
438
}
439
439
```
440
440
441
- > [运行代码](https://godbolt.org/z/hTP3ex4W7 ),打印地址完全相同。
441
+ > [运行代码](https://godbolt.org/z/zW6h1EK59 ),打印地址完全相同。
442
442
443
443
我们来解释一下,“**ref**” 其实就是 “**reference**”(引用)的缩写,意思也很简单,返回“引用”,当然了,不是真的返回引用,它们返回一个包装类 [`std::reference_wrapper`](https://zh.cppreference.com/w/cpp/utility/functional/reference_wrapper),顾名思义,这个类就是包装引用对象类模板,将对象包装,可以隐式转换为被包装对象的引用。
444
444
0 commit comments