电子产业一站式赋能平台

PCB联盟网

搜索
查看: 169|回复: 0
收起左侧

《Effective Modern C++》读书笔记(1):类型推导、auto

[复制链接]

1077

主题

1077

帖子

1万

积分

论坛法老

Rank: 6Rank: 6

积分
11496
发表于 2024-3-13 08:31:00 | 显示全部楼层 |阅读模式

uakjpltlpsi64067742321.png

uakjpltlpsi64067742321.png
9 K+ m; \# }. m8 [' q/ G$ y
' a3 i, G6 e8 x( E1 t' `3 z
最近有小伙伴说没有收到当天的文章推送,这是因为微信改了推送机制,有一部分小伙伴刷不到当天的文章,一些比较实用的知识和信息,错过了就是错过了,建议大家加个星标??,就能第一时间收到推送' H* [8 Q6 M( \( F' f3 W, M& K

52zwn2ncu4164067742421.png

52zwn2ncu4164067742421.png

% q  t+ D; H( j1 q    虽然《Effective C++》系列已讲了足够多的知识点,我都多少有些头昏脑胀了,但很可惜C++入门之旅仍然没有结束。- `* x# {; C( X7 a
    C++11/14标准堪称脱胎换骨,有必要先读完这本《Effective Modern C++》,学习11/14的新特性和习惯做法,而后再阅读源码或上手自己的项目。- }0 M$ {  F1 b& r

+ p( J* z! b& T+ ~' ?, e条款1、理解模板类型推导/ I1 b( J: V; D8 P( m9 T+ E# u
    考虑这种形式,T为模板参数,ParamType为形参,expr为实参:1 P" b1 F  i( ~/ }
  • templatetypename T>void f(ParamType param);
    . d7 m/ @- |" t% o3 J% wf(expr);
    ; k" V9 @8 ]. C. _8 k# C    在模板类型推导时,实参的引用性会被忽略;若形参还是按值传递时(T),实参的const、volatile也会被忽略。
    , P, o( j) y1 x; W$ J* Y
  • templatetypename T>void f(T& param);1 \" Z. b2 L, ~* S9 t
    int x = 27;const int cx = x;const int &rx = x;// T为int,形参为int&  f(x);   // T为const int,形参为const int&f(cx); // 忽略rx的引用性,T为const int,形参为const int& f(rx);
    " x( T5 [0 F$ P4 }3 o6 G* E( j+ i    而形参是万能引用时,若实参是右值,情况与上面相同;若实参是左值,情况发生变化,T和形参都被推导为左值引用。至于什么是万能引用、左值右值,后续会讲。
    9 `& x* O0 C) S3 D    模板类型推导过程中,数组或函数型别的实参会退化成对应指针,除非形参是引用(T&)。" l( z  M5 e0 R! H! H

    % l) h1 U; v, ^* X0 |: a5 E9 ^  ?条款2、理解auto类型推导
    3 V+ j4 R( [' ^! s    auto类型推导基本上和模板类型推导一样。
    4 P, U. b3 }; i5 e
  • const auto& rx = x;//rx的类型推导类似下面paramtemplatevoid f(const T& param);
    / q4 |: J* f  f6 y8 i2 g8 N    唯一例外在于auto会假定大括号初始化表达式代表一个std::initializer_list,而模板类型推导无法处理。
    6 j% |- z- U" X8 h# Q7 i7 e
  • // x是std::initializer_listauto x = { 11, 23, 9 }; // 无法编译templatetypename T>void f(T param);
    4 ?/ s' K& j( ^2 I6 Wf({ 11, 23, 9})+ b6 s1 i$ g4 _3 X$ n
        此外,C++14中在函数返回值或lambda的形参中的auto使用的是模板类型推导。/ b, V0 D5 `2 _& H, S
    条款3、理解decltype# i8 ?' ?& E8 T1 C5 Y
        绝大多数情况下,不同于模板与auto,decltype会得出变量或表达式的类型而不作任何更改。' m+ g6 H2 R5 G9 I: E. x0 d
  • bool f(const Widget& w);decltype(w)是const Widget&decltype(f)是bool(const Widget&)decltype(f(w))是bool    C++14支持decltype(auto),它像auto一样自动推导类型,但用的是decltype的规则,可以用于函数返回值或变量声明。
    7 z5 x  p% a. N# |/ o# l" B
  • //C++11支持返回值型别尾序语法//返回auto时需要将返回值类型置于形参列表后templateauto At(Container& c, Index i) -> decltype(c){  return c;}//C++14返回值只需auto即可,但类型推导规则可能出错//例如下面auto推导时去除了c的引用性,无法给c赋值templateauto At(Container& c, Index i) {  return c;}//采用decltype(auto)即可templatedecltype(auto) At(Container& c, Index i) {  return c;}//考虑左值右值,需要用万能引用和forward//具体后文再讲templatedecltype(auto) At(Container&& c, Index i){  return std::forward(c);}+ ~/ {# r/ w$ U: c0 [! I- [
        decltype推导规则的例外是对于比仅有名字更复杂的左值表达式(名字是左值表达式),decltype得出的类型总是左值引用。, U' J( n; ^/ R( `0 M6 n0 i4 d
  • decltype(auto) Func(){  int x = 0;  //只有名字,返回int  return x;  //比名字更复杂,返回int&  return (x);}& X; T; e8 t5 N) c" p* j
    - D4 l! P" _1 L2 |) G
    条款4、掌握查看类型推导结果的方法
    ; }- ~: _+ k6 i* ^    利用IDE编辑器、编译器错误消息和Boost.TypeIndex库常常能够查看到推导而得的类型。) r0 w0 k$ b' H8 V7 E& m, |) p
        但有时结果可能无用或不准确,因此有必要理解C++类型推导规则。  S4 |2 c3 y$ Z  t' w8 |

    7 F7 r& }8 M+ l" P+ G! x条款5、优先选用auto,而非显式类型声明
    . S/ C, h' N. N5 Y' c" {( C    auto变量必须初始化,不仅仅可以比显式指定类型少打字,还可以避免类型不匹配时不想要也没想到的隐式类型转换。
    : O5 b2 s1 C- {+ x
  • std::unordered_mapstd::string, int> m;//p的类型应该是std::pair//导致拷贝了一系列临时对象,不仅增加了成本,还无法取得p真正地址for (const std::pairstd::string, int> &p : m)//没有上述问题for (const auto &p : m). ?/ Y' O1 \3 R9 H5 h
        条款2和条款6描述了auto的缺点。
    3 W& P# ]6 i1 h6 b) r: ~2 {6 s& D2 {! X
    , N' I- `" _* e' Y
    条款6、当auto推导的类型不符合要求时,使用显式类型
    / c' K4 x+ k5 m4 g    隐形的代理类型可以导致auto根据初始化表达式推导出不符合预期的类型。
    5 p6 T1 O- Y% a0 c* x9 Z5 P    例如正常的std::vector::operator[]返回元素的引用,但对于bool来说由于C++禁止比特的引用,所以std::vector::operator[]返回std::vector::reference这个代理类来隐式转换成bool。
    ; D. y1 Z, t  ^8 ?1 s) ]; K/ A
  • vectorbool> vec(10);//隐式转换成bool,类型正确bool flag = vec[0];//flag类型是std::vector::referenceauto flag = vec[0];编程资源&影视资源分享近期发现了一份 20T各类编程/影视/学习资源的腾讯文档,其中除了互联网编程学习资源外,还有不少影视资源,分享给各位:- ?! O- }4 l1 ]4 M/ N  {
    / ^, S) I- U2 t8 r7 N7 \

    vhi1wihzqbc64067742521.png

    vhi1wihzqbc64067742521.png

    ! `+ p! ]* s  m2 Z, B$ h7 T$ Y' @9 B! W% }# R: y5 b3 {

    uqss3roohzq64067742622.png

    uqss3roohzq64067742622.png

    * ~+ k) f/ g0 |0 c1 P9 Y1 [2 ^5 ^/ n+ g4 F; l# G9 A9 y

    zdlqgfssr0564067742722.png

    zdlqgfssr0564067742722.png
    4 M9 L8 m6 V5 F7 M: ^) ~& J
    资源链接:https://docs.qq.com/sheet/DY3VPVklVaFFMcUZ4?tab=9h5afr  (右键复制到浏览器地址栏打开),或者点击文末「阅读原文」也可查看。7 C' R2 S. r" I- D3 o6 @) B
    欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些好用工具、白嫖福利、各类资源以及工作体验,还有一些内推机会。1 O0 o/ Q& G0 l9 Q+ x9 d: \( o

    sulkq0s4ns064067742823.png

    sulkq0s4ns064067742823.png

    0 }" Z' J) f" @5 I加个微信,打开另一扇窗
    # \1 C% c/ a+ y2 r$ ~; i  s  X0 L

    lehmpglpyto64067742923.gif

    lehmpglpyto64067742923.gif
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表