|
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
% 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* Ytemplatetypename 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 econst 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- {+ xstd::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/ Avectorbool> 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
! `+ p! ]* s m2 Z, B$ h7 T$ Y' @9 B! W% }# R: y5 b3 {
uqss3roohzq64067742622.png
* ~+ k) f/ g0 |0 c1 P9 Y1 [2 ^5 ^/ n+ g4 F; l# G9 A9 y
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
0 }" Z' J) f" @5 I加个微信,打开另一扇窗
# \1 C% c/ a+ y2 r$ ~; i s X0 L
lehmpglpyto64067742923.gif
|
|