@@ -429,16 +429,62 @@ <h3 id="_1">返回引用类型</h3>
429
429
</ blockquote >
430
430
< p > 这就是为什么 < code > int &&</ code > 就只是右值引用,而 < code > auto &&</ code > 以及 < code > T &&</ code > 则会叫做万能引用。一旦允许前面的参数为 < code > auto</ code > 或者模板参数,就可以代换,就可以实现左右通吃。</ p >
431
431
< h3 id ="decltypeauto "> 真正的万能 < code > decltype(auto)</ code > </ h3 >
432
+ < p > 返回类型声明为 < code > decltype(auto)</ code > 的效果等价于把返回类型替换为 < code > decltype((返回表达式))</ code > :</ p >
433
+ < pre > < code class ="language-cpp "> int i;
434
+
435
+ decltype(auto) func() {
436
+ return i;
437
+ }
438
+ // 等价于:
439
+ decltype((i)) func() {
440
+ return i;
441
+ }
442
+ // 等价于:
443
+ int &func() {
444
+ return i;
445
+ }
446
+ </ code > </ pre >
447
+ < blockquote >
448
+ < p > < img src ="../img/warning.png " height ="30px " width ="auto " style ="margin: 0; border: none "/> 注意 < code > decltype(i)</ code > 是 < code > int</ code > 而 < code > decltype((i))</ code > 是 < code > int &</ code > 。这是因为 < code > decltype</ code > 实际上有两个版本!当 < code > decltype</ code > 中的内容只是单独的一个标识符(变量名)时,会得到变量定义时的类型;而当 < code > decltype</ code > 中的内容不是单纯的变量名,而是一个复杂的表达式时,就会进入 < code > decltype</ code > 的第二个版本:表达式版,会求表达式的类型,例如当变量为 < code > int</ code > 时,表达式 < code > (i)</ code > 的类型是左值引用,< code > int &</ code > ,而变量本身 < code > i</ code > 的类型则是 < code > int</ code > 。此处加上 < code > ()</ code > 就是为了让 < code > decltype</ code > 被迫进入“表达式”的那个版本,< code > decltype(auto)</ code > 遵循的也是“表达式”这个版本的结果。</ p >
449
+ </ blockquote >
450
+ < pre > < code class ="language-cpp "> int i;
451
+
452
+ decltype(auto) func() {
453
+ return i;
454
+ }
455
+ // 等价于:
456
+ decltype((i + 1)) func() {
457
+ return i + 1;
458
+ }
459
+ // 等价于:
460
+ int func() {
461
+ return i + 1;
462
+ }
463
+ </ code > </ pre >
464
+ < pre > < code class ="language-cpp "> int i;
465
+
466
+ decltype(auto) func() {
467
+ return std::move(i);
468
+ }
469
+ // 等价于:
470
+ decltype((std::move(i))) func() {
471
+ return std::move(i);
472
+ }
473
+ // 等价于:
474
+ int &&func() {
475
+ return std::move(i);
476
+ }
477
+ </ code > </ pre >
432
478
< p > 以上介绍的这些引用推导规则,其实也适用于局部变量的 < code > auto</ code > ,例如:</ p >
433
- < pre > < code class ="language-cpp "> auto i = 0; // int i = 0
434
- auto &ref = i; // int &ref = i
435
- auto const &cref = i; // int const &cref = i
436
- auto &&rvref = move(i); // int &&rvref = move(i)
479
+ < pre > < code class ="language-cpp "> auto i = 0; // int i = 0
480
+ auto &ref = i; // int &ref = i
481
+ auto const &cref = i; // int const &cref = i
482
+ auto &&rvref = std:: move(i); // int &&rvref = move(i)
437
483
438
- decltype(auto) j = i; // int j = i
439
- decltype(auto) k = ref; // int &k = ref
484
+ decltype(auto) j = i; // int j = i
485
+ decltype(auto) k = ref; // int &k = ref
440
486
decltype(auto) l = cref; // int const &l = cref
441
- decltype(auto) m = move(rvref); // int &&m = rvref
487
+ decltype(auto) m = std:: move(rvref); // int &&m = rvref
442
488
</ code > </ pre >
443
489
< h2 id ="for-auto "> 范围 for 循环中的 < code > auto &</ code > </ h2 >
444
490
< p > 众所周知,在 C++11 的“范围 for 循环” (range-based for loop) 语法中,< code > auto</ code > 的出镜率很高。</ p >
0 commit comments