Skip to content

Commit e6e2b0f

Browse files
changkunHarrisonDing
authored andcommitted
book: translate ch03
see changkun#12
1 parent b13a243 commit e6e2b0f

15 files changed

+808
-180
lines changed

Diff for: book/en-us/03-runtime.md

+605
Large diffs are not rendered by default.

Diff for: book/en-us/toc.md

+3-7
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,13 @@
4242
- [**Chapter 03 Language Runtime Enhancements**](./03-runtime.md)
4343
+ 3.1 Lambda expression
4444
+ Basics
45-
+ Value capture
46-
+ Reference capture
47-
+ Implicit capture
48-
+ Expression capture
49-
+ Generic lambda
45+
+ Generics
5046
+ 3.2 Function object wrapper
5147
+ std::function
5248
+ std::bind/std::placeholder
5349
+ 3.3 rvalue reference
5450
+ lvalue, rvalue, prvalue, xvalue
55-
+ rvalue reference & lvalue reference
51+
+ rvalue reference and lvalue reference
5652
+ Move semantics
5753
+ Perfect forwarding
5854
- [**Chapter 04 Containers**](./04-containers.md)
@@ -87,7 +83,7 @@
8783
+ 7.4 Condition Variable
8884
+ 7.5 Atomic Operation and Memory Model
8985
+ Atomic Operation
90-
+ Concistency Model
86+
+ Consistency Model
9187
+ Memory Orders
9288
- [**Chapter 08 File System**](./08-filesystem.md)
9389
+ 8.1 Documents and links

Diff for: book/zh-cn/03-runtime.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,8 @@ void foo() {
317317
}
318318
```
319319
320-
由于 int& 不能引用 double 类型的参数,因此必须产生一个临时值来保存 s 的值,
321-
从而当 increase() 修改这个临时值时,从而调用完成后 s 本身并没有被修改。
320+
由于 `int&` 不能引用 `double` 类型的参数,因此必须产生一个临时值来保存 `s` 的值,
321+
从而当 `increase()` 修改这个临时值时,从而调用完成后 `s` 本身并没有被修改。
322322
323323
第二个问题,为什么常量引用允许绑定到非左值?原因很简单,因为 Fortran 需要。
324324

Diff for: book/zh-cn/toc.md

+3-7
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,11 @@
4141
- 强类型枚举
4242
- [**第 3 章 语言运行期的强化**](./03-runtime.md)
4343
+ 3.1 lambda 表达式
44-
+ lambda 表达式基础
45-
+ 值捕获
46-
+ 引用捕获
47-
+ 隐式捕获
48-
+ 表达式捕获
49-
+ 泛型 lambda
44+
+ 基础
45+
+ 泛型
5046
+ 3.2 函数对象包装器
5147
+ std::function
52-
+ std::bind/std::placeholder
48+
+ std::bindstd::placeholder
5349
+ 3.3 右值引用
5450
+ 左值、右值的纯右值、将亡值、右值
5551
+ 右值引用和左值引用

Diff for: code/3/3.1.cpp

-55
This file was deleted.

Diff for: code/3/3.1.lambda.basic.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//
2+
// 3.1.lambda.basic.cpp
3+
// chapter 03 runtime enhancement
4+
// modern c++ tutorial
5+
//
6+
// created by changkun at changkun.de
7+
// https://github.com/changkun/modern-cpp-tutorial
8+
//
9+
10+
11+
#include <iostream>
12+
#include <utility>
13+
14+
void lambda_value_capture() {
15+
int value = 1;
16+
auto copy_value = [value] {
17+
return value;
18+
};
19+
value = 100;
20+
auto stored_value = copy_value();
21+
std::cout << "stored_value = " << stored_value << std::endl;
22+
// At this moment, stored_value == 1, and value == 100.
23+
// Because copy_value has copied when its was created.
24+
}
25+
26+
void lambda_reference_capture() {
27+
int value = 1;
28+
auto copy_value = [&value] {
29+
return value;
30+
};
31+
value = 100;
32+
auto stored_value = copy_value();
33+
std::cout << "stored_value = " << stored_value << std::endl;
34+
// At this moment, stored_value == 100, value == 100.
35+
// Because copy_value stores reference
36+
}
37+
38+
void lambda_expression_capture() {
39+
auto important = std::make_unique<int>(1);
40+
auto add = [v1 = 1, v2 = std::move(important)](int x, int y) -> int {
41+
return x+y+v1+(*v2);
42+
};
43+
std::cout << add(3,4) << std::endl;
44+
}
45+
46+
void lambda_generic() {
47+
auto generic = [](auto x, auto y) {
48+
return x+y;
49+
};
50+
51+
std::cout << generic(1, 2) << std::endl;
52+
std::cout << generic(1.1, 2.2) << std::endl;
53+
}
54+
55+
int main() {
56+
lambda_value_capture();
57+
lambda_reference_capture();
58+
lambda_expression_capture();
59+
lambda_generic();
60+
return 0;
61+
}
+14-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
//
2-
// 3.2.cpp
2+
// 3.2.function.wrap.cpp
3+
// chapter 03 runtime enhancement
34
// modern c++ tutorial
45
//
56
// created by changkun at changkun.de
67
// https://github.com/changkun/modern-cpp-tutorial
78
//
8-
// std::function std::bind
99

1010
#include <functional>
1111
#include <iostream>
1212

13-
using foo = void(int); // 定义函数指针
13+
using foo = void(int); // function pointer
1414
void functional(foo f) {
1515
f(1);
1616
}
@@ -24,29 +24,28 @@ int foo3(int a, int b, int c) {
2424
}
2525

2626
int main() {
27-
27+
2828
auto f = [](int value) {
2929
std::cout << value << std::endl;
3030
};
31-
functional(f); // 函数指针调用
32-
f(1); // lambda 表达式调用
33-
34-
// std::function 包装了一个返回值为 int, 参数为 int 的函数
31+
functional(f); // call by function pointer
32+
f(1); // call by lambda expression
33+
34+
// std::function wraps a function that take int paremeter and returns int value
3535
std::function<int(int)> func = foo2;
36-
36+
3737
int important = 10;
3838
std::function<int(int)> func2 = [&](int value) -> int {
3939
return 1+value+important;
4040
};
4141
std::cout << func(10) << std::endl;
4242
std::cout << func2(10) << std::endl;
43-
44-
45-
// 将参数1,2绑定到函数 foo 上,但是使用 std::placeholders::_1 来对第一个参数进行占位
43+
44+
// bind parameter 1, 2 on function foo, and use std::placeholders::_1 as placeholder
45+
// for the first parameter.
4646
auto bindFoo = std::bind(foo3, std::placeholders::_1, 1,2);
47-
// 这时调用 bindFoo 时,只需要提供第一个参数即可
47+
// when call bindFoo, we only need one param left
4848
bindFoo(1);
49-
50-
49+
5150
return 0;
5251
}

Diff for: code/3/3.3.cpp

-39
This file was deleted.

Diff for: code/3/3.3.rvalue.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//
2+
// 3.3.rvalue.cpp
3+
// modern c++ tutorial
4+
//
5+
// created by changkun at changkun.de
6+
// https://github.com/changkun/modern-cpp-tutorial
7+
//
8+
9+
10+
#include <iostream>
11+
#include <string>
12+
13+
void reference(std::string& str) {
14+
std::cout << "lvalue" << std::endl;
15+
}
16+
void reference(std::string&& str) {
17+
std::cout << "rvalue" << std::endl;
18+
}
19+
20+
int main()
21+
{
22+
std::string lv1 = "string,"; // lv1 is a lvalue
23+
// std::string&& r1 = s1; // illegal, rvalue can't ref to lvalue
24+
std::string&& rv1 = std::move(lv1); // legal, std::move can convert lvalue to rvalue
25+
std::cout << rv1 << std::endl; // string,
26+
27+
const std::string& lv2 = lv1 + lv1; // legal, const lvalue reference can extend temp variable's lifecycle
28+
// lv2 += "Test"; // illegal, const ref can't be modified
29+
std::cout << lv2 << std::endl; // string,string
30+
31+
std::string&& rv2 = lv1 + lv2; // legal, rvalue ref extend lifecycle
32+
rv2 += "string"; // legal, non-const reference can be modified
33+
std::cout << rv2 << std::endl; // string,string,string,
34+
35+
reference(rv2); // output: lvalue
36+
37+
return 0;
38+
}

Diff for: code/3/3.4.historical.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// 3.4.historical.cpp
3+
// modern c++ tutorial
4+
//
5+
// created by changkun at changkun.de
6+
// https://github.com/changkun/modern-cpp-tutorial
7+
//
8+
9+
#include <iostream>
10+
11+
int main() {
12+
// int &a = std::move(1); // illegal, non-const lvalue reference cannot ref rvalue
13+
const int &b = std::move(1); // legal, const lvalue reference can
14+
15+
std::cout << b << std::endl;
16+
}

Diff for: code/3/3.4.cpp renamed to code/3/3.5.move.semantics.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,35 @@
11
//
2-
// 3.4.cpp
2+
// 3.5.move.semantics.cpp
33
// modern c++ tutorial
44
//
55
// created by changkun at changkun.de
66
// https://github.com/changkun/modern-cpp-tutorial
77
//
8-
// 移动语义
98

109
#include <iostream>
1110
class A {
1211
public:
1312
int *pointer;
1413
A():pointer(new int(1)) {
15-
std::cout << "构造" << pointer << std::endl;
14+
std::cout << "construct" << pointer << std::endl;
1615
}
1716
A(A& a):pointer(new int(*a.pointer)) {
18-
std::cout << "拷贝" << pointer << std::endl;
19-
} // 无意义的对象拷贝
17+
std::cout << "copy" << pointer << std::endl;
18+
} // meaningless object copy
2019
A(A&& a):pointer(a.pointer) {
2120
a.pointer = nullptr;
22-
std::cout << "移动" << pointer << std::endl;
21+
std::cout << "move" << pointer << std::endl;
2322
}
2423
~A(){
25-
std::cout << "析构" << pointer << std::endl;
24+
std::cout << "destruct" << pointer << std::endl;
2625
delete pointer;
2726
}
2827
};
29-
// 防止编译器优化
28+
// avoid compiler optimization
3029
A return_rvalue(bool test) {
3130
A a,b;
32-
if(test) return a; // 等价于 static_cast<A&&>(a);
33-
else return b; // 等价于 static_cast<A&&>(b);
31+
if(test) return a; // equal to static_cast<A&&>(a);
32+
else return b; // equal to static_cast<A&&>(b);
3433
}
3534
int main() {
3635
A obj = return_rvalue(false);

0 commit comments

Comments
 (0)