Skip to content

Commit 1fe985e

Browse files
committed
update concept
1 parent 7256ed4 commit 1fe985e

File tree

2 files changed

+633
-10
lines changed

2 files changed

+633
-10
lines changed

docs/auto.md

+59-7
Original file line numberDiff line numberDiff line change
@@ -200,18 +200,70 @@ auto const &getConstRef() { // std::string const &
200200

201201
### 真正的万能 `decltype(auto)`
202202

203+
返回类型声明为 `decltype(auto)` 的效果等价于把返回类型替换为 `decltype((返回表达式))`
204+
205+
```cpp
206+
int i;
207+
208+
decltype(auto) func() {
209+
return i;
210+
}
211+
// 等价于:
212+
decltype((i)) func() {
213+
return i;
214+
}
215+
// 等价于:
216+
int &func() {
217+
return i;
218+
}
219+
```
220+
221+
> {{ icon.warn }} 注意 `decltype(i)` 是 `int` 而 `decltype((i))` 是 `int &`。这是因为 `decltype` 实际上有两个版本!当 `decltype` 中的内容只是单独的一个标识符(变量名)时,会得到变量定义时的类型;而当 `decltype` 中的内容不是单纯的变量名,而是一个复杂的表达式时,就会进入 `decltype` 的第二个版本:表达式版,会求表达式的类型,例如当变量为 `int` 时,表达式 `(i)` 的类型是左值引用,`int &`,而变量本身 `i` 的类型则是 `int`。此处加上 `()` 就是为了让 `decltype` 被迫进入“表达式”的那个版本,`decltype(auto)` 遵循的也是“表达式”这个版本的结果。
222+
223+
```cpp
224+
int i;
225+
226+
decltype(auto) func() {
227+
return i;
228+
}
229+
// 等价于:
230+
decltype((i + 1)) func() {
231+
return i + 1;
232+
}
233+
// 等价于:
234+
int func() {
235+
return i + 1;
236+
}
237+
```
238+
239+
```cpp
240+
int i;
241+
242+
decltype(auto) func() {
243+
return std::move(i);
244+
}
245+
// 等价于:
246+
decltype((std::move(i))) func() {
247+
return std::move(i);
248+
}
249+
// 等价于:
250+
int &&func() {
251+
return std::move(i);
252+
}
253+
```
254+
203255
以上介绍的这些引用推导规则,其实也适用于局部变量的 `auto`,例如:
204256
205257
```cpp
206-
auto i = 0; // int i = 0
207-
auto &ref = i; // int &ref = i
208-
auto const &cref = i; // int const &cref = i
209-
auto &&rvref = move(i); // int &&rvref = move(i)
258+
auto i = 0; // int i = 0
259+
auto &ref = i; // int &ref = i
260+
auto const &cref = i; // int const &cref = i
261+
auto &&rvref = std::move(i); // int &&rvref = move(i)
210262
211-
decltype(auto) j = i; // int j = i
212-
decltype(auto) k = ref; // int &k = ref
263+
decltype(auto) j = i; // int j = i
264+
decltype(auto) k = ref; // int &k = ref
213265
decltype(auto) l = cref; // int const &l = cref
214-
decltype(auto) m = move(rvref); // int &&m = rvref
266+
decltype(auto) m = std::move(rvref); // int &&m = rvref
215267
```
216268

217269
## 范围 for 循环中的 `auto &`

0 commit comments

Comments
 (0)