C++11语法糖
C++读书笔记(牛客网)
1.constexpr变量:声明为constexpr的变量一定是一个常量,新标准允许定义一种特殊的constexpr函数使得编译时就可计算结果,这样就能用constexpr函数去初始化constexpr变量。
2.类型别名:1.typedef 2.using SI = Sales_item; //SI是Sales_item的别名声明,把等号左侧的名字规定成等号右侧类型的别名 3.using可以起模板别名
3.auto:auto让编译器通过初始值来推算变量类型。auto i = 0, *p = &i; //ok auto sz = 0, pi = 3.14; //error, 类型不统一
auto一般会忽略顶层const,保留底层const。如果希望保留顶层const,要明确指出 const auto p = ci;
设置类型为auto的引用时,初始值中的顶层const属性保留。
底层 * 顶层: int const * const
4.decltype:类型指示符,顶层const能被保留,decltype((i)) d; //error, 对表达式套括号的结果永远是引用,不套括号则仅当i是引用时,才是引用。
5.范围for语句:for(declaration: expression) statement
expression是一个对象,表示一个序列;declaration部分定义一个变量,被用于访问序列中的基础元素,每次迭代该变量会被初始化为expression的下一个元素值。
如:
- vector<int> v = {, , , , , };
- for(auto &r: v)
- r *= ;
6.标准库begin()和end():begin(arr)返回指向arr首元素的指针, end(arr)返回指向arr尾元素下一位置的指针。
7.列表初始化返回值:vector<string> f(){ if(true) return {}; else return {"fun", "ok"}; }
8.定义尾置返回类型:任何函数的定义都能使用尾置返回类型,但对返回类型比较复杂的函数最有效,比如返回数组的指针或数组的引用。尾置返回类型跟在形参列表后,并以->开头,本应该出现返回类型的地方则放置auto。比如:
auto func(int i) -> int(*) [10];//返回类型为int(*)[10]
9.容器的列表初始化:vector<const char*> articles = {"a", "an", "the"};
10.容器的emplace操作:emplace_frnont, emplace, emplace_back, 这些操作构造而不是拷贝元素,c.emplace(iter, "999-9999"); //向iter指向的位置插入以"999-9999"为构造参数的元素
11.lambda:
[ capture ] ( params ) mutable exception attribute -> ret { body } |
(1) |
[ capture ] ( params ) -> ret { body } |
(2) |
[ capture ] ( params ) { body } |
(3) |
[ capture ] { body } |
(4) |
mutable 修饰符说明 lambda 表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获对象的 non-const 方法。
exception 说明 lambda 表达式是否抛出异常(noexcept
),以及抛出何种异常,类似于void f() throw(X, Y)。
attribute 用来声明属性。
- [] // 不捕获任何外部变量
- [=] // 以值的形式捕获所有外部变量
- [&] // 以引用形式捕获所有外部变量
- [x, &y] // x 以传值形式捕获,y 以引用形式捕获
- [=, &z] // z 以引用形式捕获,其余变量以传值形式捕获
- [&, x] // x 以值的形式捕获,其余变量以引用形式捕获
- 另有一点需注意。对于 [=] 或 [&] 的形式,lambda 表达式可直接使用 this 指针。但对于 [] 的形式,如果要使用 this 指针,必须显式传入:[this]() { this->someFunc(); }();
lambda后紧接();表示直接调用函数,括号内为参数。例:
http://wenku.baidu.com/view/77cd432e647d27284b73514b.html?from=search
- std::vector<int> c { ,,,,,, };
- int x = ;
- c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; } ), c.end());
- for (auto i: c) {
- std::cout << i << ' ';
- }
- std::cout << endl;
- // the type of a closure cannot be named, but can be inferred with auto
- auto func1 = [](int i) { return i+; };
- std::cout << "func1: " << func1() << '\n';
- // like all callable objects, closures can be captured in std::function
- // (this may incur unnecessary overhead)
- std::function<int(int)> func2 = [](int i) { return i+; };
- std::cout << "func2: " << func2() << '\n';
- string result = [](const string & str) { return "Hello from " + str; }("second Lambda");
- cout << "Result: " << result << endl;
lambda的捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和它所在函数之外声明的名字。值捕获的变量的值是在lambda创建时拷贝而不是在调用时拷贝,引用捕获则使用引用所绑定的对象,与正常引用类似,要保证lambda调用时变量是存在的。
每个lambda的类型都是唯一的,一般只能通过decltype和模板匹配来获得其类型。
- vector<string> ve;
- int sz = ;
- //接受一元谓词的算法
- auto it = find_if(ve.begin(), ve.end(), [sz](const string &a){return a.size() >= sz; } );
- //接受二元谓词的算法
- sort(ve.begin(), ve.end(), [](const string &a, const string &b){ return a.size() < b.size();} );
12.标准库bind函数:
参数绑定 http://blog.csdn.net/fjb2080/article/details/7527715
auto newCallable = bind(callable, arg_list);
arg_list中的参数可能包含形如_n的名字,其中n是整数,表示newCallable的参数,占据了传递给newCallable的参数的位置,_n表示为newCallable的第n个参数,在命名空间std::placeholeders里。
- using namespace std::placeholders;
- //例1:
- bool check_size(const string &s, string::size_type sz){
- return s.size() >= sz;
- }
- auto check6 = bind(check_size, _1, );
- string s = "hello";
- bool b1 = check6(s);//check6(s)会调用check_size(s, 6)
- //例2:f是一个包含5个参数的函数
- auto g = bind(f, a, b, _2, c, _1);
- g(X, Y);//即f(a, b, Y, c, X);
- //例3:ve是vector容器,cmp是一个比较函数
- sort(ve.begin(), ve.end(), cmp);
- sort(ve.begin(), ve.end(), bind(cmp, _2, _1));//按cmp逆序排列
13.智能指针
shared_ptr允许多个指针指向同一个对象, unique_ptr则独占所指向的对象。
智能指针是一种类模板。
默认初始化的智能指针中保存着空指针,内部有一个关联的计数器,计数器为0时释放自己管理的对象。
shared_ptr<string> p4 = make_shared<string>(10, '9'); //类似顺序容器的emplace函数,使用动态内存
附: shard_ptr与unique_ptr的简单实现
- // https://www.cnblogs.com/howo/p/8468713.html
- //
- // SharedPtr.hpp
- // SharedPtr
- //
- // Created by 顾浩 on 24/2/18.
- // Copyright © 2018 顾浩. All rights reserved.
- //
- #ifndef SHARED_PTR_H
- #define SHARED_PTR_H
- #include <iostream>
- using namespace std;
- template<typename T>
- class SharedPtr {
- public:
- SharedPtr() : _ptr((T *)), _refCount()
- {
- }
- SharedPtr(T *obj) : _ptr(obj), _refCount(new int())
- {
- cout<<"create object : "<<*_ptr<<"\trefCount = 1"<<endl;
- }
- SharedPtr(SharedPtr &other) : _ptr(other._ptr), _refCount(&(++*other._refCount))
- {
- cout<<"copy constructor : "<<*_ptr<<"\trefCount = "<<*_refCount<<endl;
- }
- ~SharedPtr()
- {
- if(_ptr && --*_refCount == ) {
- cout<<*_ptr<<"\trefCount = 0. delete the _ptr:"<<*_ptr<<endl;
- delete _ptr;
- delete _refCount;
- }
- }
- SharedPtr &operator=(SharedPtr &other)
- {
- if(this==&other) return *this;
- ++*other._refCount;
- if(--*_refCount == ) {
- cout<<"in function operator = . delete "<<*_ptr<<endl;
- delete _ptr;
- delete _refCount;
- }
- _ptr = other._ptr;
- _refCount = other._refCount;
- cout<<"in function operator = . "<<*_ptr<<"\t_refCount = "<<*_refCount<<endl;
- return *this;
- }
- T *operator->()
- {
- if(_refCount == ) return ;
- return _ptr;
- }
- T &operator*()
- {
- if (_refCount == ) return (T*);
- return *_ptr;
- }
- private:
- T *_ptr;
- int *_refCount; //should be int*, rather than int
- };
- #endif /* SharedPtr_h */
- #ifndef _UNIQUE_PTR_H
- #define __UNIQUE_H
- class Delete {
- public:
- template<typename T>
- void operator()(T *p) const {
- delete p;
- }
- };
- template<typename T,typename D = Delete >
- class unique_ptr {
- public:
- explicit unique_ptr(T *pp = nullptr ,const D &dd = D() ):
- un_ptr(pp), del(dd)
- {
- }
- ~unique_ptr()
- {
- del(un_ptr);
- }
- /* 不支持拷贝与赋值 */
- unique_ptr(const unique_ptr&) = delete ;
- unique_ptr& operator=(const unique_ptr& ) = delete ;
- /* 移动赋值与移动拷贝 */
- unique_ptr( unique_ptr&& right_value):
- un_ptr(right_value.un_ptr),del(std::move(right_value.del)) {
- right_value.un_ptr = nullptr ;
- }
- unique_ptr& operator=( unique_ptr&& right_value ) noexcept {
- if(this != &right_value ){
- std::cout << "operator && right_value " << std::endl ;
- del(*this);
- un_ptr = right_value.un_ptr;
- del = std::move(right_value.del);
- right_value.un_ptr = nullptr ;
- }
- return *this ;
- }
- //u.release() u 放弃对指针的控制权,返回指针,并将 u 置为空
- T* release(){
- T *tmp = un_ptr ;
- un_ptr = nullptr ;
- return tmp;
- }
- /*
- u.reset() 释放u指向的对象
- u.reset(q) 如果提供了内置指针q,就令u指向这个对象
- u.reset(nullptr) 将 u 置为空
- */
- void reset(T* q = nullptr){
- del(un_ptr);
- un_ptr = q;
- }
- void swap(unique_ptr &other ) noexcept {
- std::swap(un_ptr, other.un_ptr);
- std::swap(del, other.del) ;
- }
- T* get() { return un_ptr; }
- D& get_deleter(){ return del; }
- T& operator*() { return *un_ptr; }
- T* operator->() { return un_ptr; }
- private:
- T *un_ptr = nullptr ;
- D del ;
- };
- #endif
C++11语法糖的更多相关文章
- C++面向对象编程之C++11语法糖
1.variadic template(模板参数可变化) template... type就是说有可变模板参数,作为参数使用时类型就是 类型后 + ... ,例如type... / type& ...
- C++11新语法糖之尾置返回类型
C++11的尾置返回类型初衷是为了方便复杂函数的声明和定义,但是当复杂度稍微提升一些的时候很明显能注意到这种设计的作用微乎其微. 首先考虑如下代码: C++ //返回指向数组的指针 auto func ...
- 基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结
随着Vue3和TypeScript的大浪潮不断袭来,越来越多的Vue项目采用了TypeScript的语法来编写代码,而Vue3的JS中的Setup语法糖也越来越广泛的使用,给我们这些以前用弱类型的JS ...
- C#语法糖大汇总
首先需要声明的是"语法糖"这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在性能上也不会带来损失.这让java开发人员羡慕 ...
- 看看C# 6.0中那些语法糖都干了些什么(终结篇)
终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...
- 看看C# 6.0中那些语法糖都干了些什么(中篇)
接着上篇继续扯,其实语法糖也不是什么坏事,第一个就是吃不吃随你,第二个就是最好要知道这些糖在底层都做了些什么,不过有一点 叫眼见为实,这样才能安心的使用,一口气上五楼,不费劲. 一:字符串嵌入值 我想 ...
- 看看C# 6.0中那些语法糖都干了些什么(上篇)
今天没事,就下了个vs2015 preview,前段时间园子里面也在热炒这些新的语法糖,这里我们就来看看到底都会生成些什么样的IL? 一:自动初始化属性 确实这个比之前的版本简化了一下,不过你肯定很好 ...
- Java语法糖4:内部类
内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...
- Java语法糖1:可变长度参数以及foreach循环原理
语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...
随机推荐
- Dll的生成,转化为OMF格式的DLL
extern "C" { __declspec(dllexport) int psq_add(int a, int b); } C:\Users\pansq>mkexp my ...
- iis配置js支持读取json文件配置
默认情况下,iis不支持解析.json文件,这就需要我们自己在iis下配置方法一:iis配置1.点击开始菜单选择控制面板: 2.控制面板内点击管理工具,选择Internet信息服务(IIS)管理器. ...
- Java 线程的转换及状态
线程的状态转换是线程控制的基础. 线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnabl ...
- paper 119:[转]图像处理中不适定问题-图像建模与反问题处理
图像处理中不适定问题 作者:肖亮博士 发布时间:09-10-25 图像处理中不适定问题(ill posed problem)或称为反问题(inverse Problem)的研究从20世纪末成为国际上的 ...
- 此操作失败的原因是对 IID 为“{000208DA-0000-0000-C000-000000000046}”的接口的 COM 组件调用 QueryInterface
有些电脑报错,有些电脑正常. 环境:VS2010 WinForm程序, Office2007 C#操作Excel时报错.错误: 无法将类型为“System.__ComObject”的 COM 对象强制 ...
- Openstack的nova-network的vlan模式扩展
openstack的nova-network的vlan模式是可以在安装的时候,将网络划分为多个子网,每个项目一个或者多个子网进行虚拟机创建.但是他现在代码级别上不支持:如果一开始安装的环境的vlan网 ...
- 七牛整合php上传从微信下载接口下载下来的文件
因为ios系统直接读取不了MP3格式的文件,所以从微信接口下载下来的MP3格式音频上传到七牛后要转码. Sample code: public function doMobileUploadT ...
- daterangepicker+ bootstrap +php +ajax +datatable双日历的使用
在练习基于bootstrap datatable的使用时,时间插件用到了daterangepicker,特做稍微了解,效果如图: 1.html <div class="panel& ...
- linux下打开、关闭tomcat,实时查看tomcat运行日志
启动:一般是执行sh tomcat/bin/startup.sh 停止:一般是执行sh tomcat/bin/shutdown.sh脚本命令 查看:执行ps -ef |grep tomcat 输出如下 ...
- javascript高级程序设计第5章,引用类型
object类型: 创建object实列的方式有两种,一种是new()方法,一种是对象字面量表示法: 第一种法方: var obj = new object(); obj.name = 'name' ...