拓冰建站拓冰建站
首页 / 资讯中心 / 正文

C++学习/复习30--{}统一列表初始化/decltype/右值引用与移动语义/perfectforward完美转发/lambda/可变参数模板/emplace/包装器function与bind

一、C11二、{ }初始化2.1{ }的使用1C98 旧版仅支持数组、结构体用{...}且必须写普通内置类型不能直接int x{2}new 表达式也不能用花括号初始化。2C11 统一初始化可以写也可以不写几乎所有类型都能用{}初始化三种对象初始化是等价的Point p0(0,0); //圆括号直接调用构造 Point p1 {1,1}; //拷贝列表初始化 Point p2{2,2}; //直接列表初始化C11推荐2.2initializer_list1底层结构编译器看到{10, 20, 30}会在常量区构造一个const int[3]数组再用两个指针包成initializer_list对象。它的底层极简元素是const T*即不能修改initializer_list本身只是个 视图不实际拥有数据。2重载决议---{}会优先匹配initializer_list构造函数只要类有接收initializer_listT的构造函数花括号初始化优先走它而不是普通构造函数。在vector中特意提供了下图所示第 (6) 号构造函数就是干这个的vectorint v1 {1,2,3,4,3}; // 调用 vector(initializer_listint)Point p1 {1,1}; // Point没有 initializer_list 构造 → 退化为聚合/两参构造3嵌套初始化 赋值运算符initializer_list不只用于构造还可以作为operator的参数让容器支持 花括号赋值上图中的mapstring,string dict 初始化时 每个内层 {} 构造一个pairconst string,string外层再构造initializer_listpairv {10, 20, 30}通过调用 operator(initializer_listint)初始化2.3工程应用注意事项1initializer_list的生命周期initializer_list底层引用的是临时常量数组生命周期与绑定它的initializer_list对象绑定。initializer_list不持有数据只持有指向底层临时数组的指针该数组的生命周期与initializer_list对象一致。不要返回局部initializer_list不要用它做长期存储。容器接收它时会立刻把元素拷贝 / 移动进自己的内存所以vectorint v {1,2,3}是安全的。2元素是const不支持移动std::initializer_list底层是const T[N]临时常量数组其元素需通过‌拷贝构造‌传入而unique_ptr删除了拷贝构造函数仅支持移动任何涉及多个unique_ptr的批量初始化必须绕过std::initializer_list的拷贝约束显式使用移动语义‌。3auto与推导规则4explicit与 explicit是 C 中用来‌禁止隐式类型转换‌的关键字注意此处有无的区别是拷贝初始化与直接初始化5窄化转换花括号初始化禁止隐式窄化这是initializer_list/ 统一初始化带来的安全特性推荐{}初始化的大理由就是防止隐式窄化更早发现类型错误。三、auto/decltype/nullptr四、STL中的新变化五、右值引用与移动语义5.1左值引用5.2右值引用5.3与const 5.4与move5.5左右值引用对比案例5.6浅拷贝/深拷贝/移动拷贝/将亡值与编译器的优化5.7万能引用与PerfectForward完美转发与左右值属性的保留六、移动构造与移动赋值七、lambda[ ]( )-{ }八、可变模板参数与参数包的展开8.1递归展开8.2逗号表达式展开九、emplace十、包装器function/函数绑定bind
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门