【深入理解C++11】第四章 新手易学,老兵易用

4.2 auto类型推导

auto在C++11中有了新的定义,例如auto a = 1;a的类型将会被推导为int类型,也可以用在例如,将会在4.4节中的追踪返回类型的函数声明,以及7.3节的lambda与auto的配合使用等等。
但是它也有一些使用限制:

  1. 不可以作为函数入参类型。
  2. 不可以非静态成员变量。
  3. 不可以使用auto数组
  4. 不可以作为模板参数
    见以下示例:
void func(auto x = 1) {} //1. 无法通过编译

struct str {
	auto var = 0;	     //2. 非静态成员,无法通过编译
};

char x[3];
auto z[3] = x;			//3. auto数组,无法通过编译

vector<auto> v = { 1 };	//4. auto模板参数,无法通过编译

4.3 decltype

4.3.1 typeid与decltype

在C++98中对动态类型支持就是C++中的运行时类型识别(RTTI)。RTTI机制是为每一个类型产生一个type_info类型的数据,程序员可以在程序中随时查询一个变量的类型。C++11提供了hash_code以方便运行时作比较。

	//C++11新增hash_code
	cout << typeid(Node).hash_code() << endl; //打印一堆数字

	float a;
	double b;
	//声明c的类型
	decltype(a + b) c;
	cout << typeid(c).name() << endl;		//打印:double

我们使用的std::is_same模板函数的成员类型value,是在编译器得到类型信息,不同的是hash_code是运行时得到的信息。
除了typeid以外,RTTI也包括了dynamic_cast等特性。要记得RTTI确实会带来一些开销。

4.3.2 decltype的应用

一些简单的使用如下:

vector<int> vec;
typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin(); i < vec.end(); ++i) {}

template<typename T1, typename T2>
void sum(T1 &t1, T2 &t2, decltype(t1 + t2) &s)
{
	s = t1 + t2;
}

一个来自标准库的典型的例子是基于decltype的模板result_of,作用是推导函数的返回类型。

namespace gxlemon
{
	template<typename>
	struct result_of;

	template<typename F, typename ...Args>
	struct result_of<F(Args...)>
	{
		typedef decltype(std::declval<F>()(std::declval<Args>()...)) type;
	};
}

//使用如下
typedef double(*pFunc)();
//要求模板参数 是一种类型,而不是具体的某个对象
//这样a就是该函数类型的返回类型
gxlemon::result_of<pFunc()>::type a;
4.3.3 decltype推导四规则
		int i;
		decltype(i) a;
		decltype((i)) b;  //“b”: 必须初始化引用

通过decltype(e)获取类型时,编译器根据以下四个规则推导:

  1. 如果e是一个没有带括号的标记符表达式,或者类成员访问表达式,那么decltype(e)就是e的实体类型。另外e如果是一个重载函数,将会编译错误。
  2. 否则,假设e是类型T,如果e是一个将亡值(xvalue),那么decltype(e)为T&&。
  3. 否则,假设e是类型T,如果e是一个左值,则decltype(e)为T&。
  4. 否则,假设e是类型T,则decltype(e)为T。
    简单举例解释一下标记符表达式int arr[4],arr就是一个标记符表达式,例如arr[3] + 0, arr[3],都不是标记符表达式。

推导示例如下(书籍代码清单4-25):
在这里插入图片描述
注意左值引用总是需要初始化的。C++11标准库提供了is_lvalue_reference模板类来帮助判断一个推导结果。
示例见书籍代码清单4-26
在这里插入图片描述

4.3.4 cv限制符的继承与冗余的符号

与auto类型推导时不能带走cv限制符不同,decltype是能“带走”表达式的cv限制符的。如果对象的定义中含有const或者volatile则使用decltype进行推导时其成员不会继承const或volatile限制符,看一下示例:

		const int ic = 0;
		volatile int iv;

		struct S { int i; };

		const S a = { 0 };
		volatile S b;
		volatile S *p = &b;

		cout << "is_const<decltype(ic)>::value " << is_const<decltype(ic)>::value << endl;
		cout << "is_volatile<decltype(iv)>::value "<< is_volatile<decltype(iv)>::value << endl;
		cout << "is_const<decltype(a)>::value " << is_const<decltype(a)>::value << endl;
		cout << "is_volatile<decltype(b)>::value " << is_volatile<decltype(b)>::value << endl;
		cout << "is_const<decltype(a.i)>::value " << is_const<decltype(a.i)>::value << endl;
		cout << "is_volatile<decltype(b.i)>::value " << is_volatile<decltype(b.i)>::value << endl;

在这里插入图片描述
与auto相同,decltype从表达式推导出类型后,进行类型定义时,也会允许一些冗余符号,比如cv限制符和引用符号&。
在这里插入图片描述

4.4 追踪返回类型

4.4.1 追踪返回类型的引入

直接看一个例子,我们需要一个泛型的sum函数,入参我们可以通过模板实现,但是返回值就不太好处理了,所以我们需要一个可以承载任何类型的返回值。

//C++编译器规则:变量使用前必须声明,所以可以追踪返回类型,见下例子
template<typename T1, typename T2>
decltype(t1 + t2) sum1(T1 t1, T2 t2)
{
	return t1 + t2;
}

template<typename T1, typename T2>
auto  sum2(T1 t1, T2 t2) -> decltype(t1 + t2)
{
	return t1 + t2;
}
4.4.2 使用追踪返回类型的函数

看一个题目:

//可能是一个面试题
int(*(*pf())())()
{
	return nullptr;
}

//		   -> 返回一个a函数的指针的函数 -> 返回一个函数指针a
auto pf1() -> auto (*)() -> int(*)()
{
    return nullptr;
}

可以看到我们可以使用返回类型跟踪很方便的声明该类型,以下见详细代码:

//声明函数指针类型
typedef int(*PFUNC)();

//一个函数 返回int
int fun()
{
	return 1;
}

//返回一个函数指针
PFUNC funRetPF()
{
	return fun;
}

//声明返回一个函数指针的类型
typedef int(*(*PFUNCRETFUN)())();

//可能是一个面试题
int(*(*pf())())()
{
	PFUNCRETFUN f = funRetPF;
	return f;
}

//		   -> 返回一个a函数的指针的函数 -> 返回一个函数指针a
auto pf1() -> auto (*)() -> int(*)()
{
	PFUNCRETFUN f = funRetPF;
	return f;
}
	cout << std::is_same<decltype(pf1), decltype(pf)>::value << endl;

	cout << "pf1: " << pf1()()() << endl;
	cout << "pf : " << pf()()() << endl;

4.5 基于范围的for循环

只需要注意,迭代for循环时,源迭代对象不能发生变化,例如删除对象等操作,以下是一个示例:

std::vector<int> gVecs;

void fun()
{
	for (int i = 0; i < 100; ++i)
	{
		gVecs.pop_back();
	}
}

int main()
{
	for (int i = 0; i < 200; ++i)
	{
		gVecs.push_back(i);
	}
	thread thd(fun);
	//迭代
	for (int val : gVecs)
	{
		if (val == 50)	//触发线程删除部分元素
		{
			thd.detach();
		}
		cout << val << " ";
	}
	getchar();
	return 0;
}

运行后发现崩溃,可以发现迭代对象的end已经超过当前容器的大小100(其他元素在线程中删除了)。
在这里插入图片描述

MySQL数据库从入门实战课

12-31
限时福利1:购课进答疑群专享柳峰(刘运强)老师答疑服务。 限时福利2:购课后添加学习助手(微信号:csdn590),按消息提示即可领取编程大礼包! 注意:原价129的课程,最后2天限时秒杀仅需49元!! 为什么说每一个程序员都应该学习MySQL? 根据《2019-2020年中国开发者调查报告》显示,超83%的开发者都在使用MySQL数据库。 使用量大同时,掌握MySQL早已是运维、DBA的必备技能,甚至部分IT开发岗位也要求对数据库使用和原理有深入的了解和掌握。 学习编程,你可能会犹豫选择 C++ 还是 Java;入门数据科学,你可能会纠结于选择 Python 还是 R;但无论如何, MySQL 都是 IT 从业人员不可或缺的技能! 【课程设计】 在本课程中,刘运强老师会结合自己十多年来对MySQL的心得体会,通过课程给你分享一条高效的MySQL入门捷径,让学员少走弯路,彻底搞懂MySQL。 本课程包含3大模块:  一、基础篇: 主要以最新的MySQL8.0安装为例帮助学员解决安装与配置MySQL的问题,并对MySQL8.0的新特性做一定介绍,为后续的课程展开做好环境部署。 二、SQL语言篇: 本篇主要讲解SQL语言的四大部分数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL,学会熟练对库表进行增删改查等必备技能。 三、MySQL进阶篇: 本篇可以帮助学员更加高效的管理线上的MySQL数据库;具备MySQL的日常运维能力,语句调优、备份恢复等思路。  

Python入门到实战一卡通

06-09
<span><span><span><span> <p class="ql-long-24357476"> <span> </span> </p> <p class="ql-long-24357476"> 【课程特色】 </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、超强师资+体系全面+ 1 对 1 答疑+离线缓存+永久有效,无限回放</span> </p> <p class="ql-long-24357476"> 2、知识全面系统,从Python入门到逐步进阶到爬虫、数据分析、Web框架、人工智能应用 </p> <p class="ql-long-24357476"> <br> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">【优惠说明】</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">1、8大课程,250余节视频课,原价998元,今日联报立减800,仅需198元</span> </p> <p class="ql-long-24357476"> <span class="ql-author-24357476">2、</span>现在购课,就送价值800元的编程大礼包! </p> <p class="ql-long-24357476"> 备注:请添加微信:itxy41,按提示获取讲师答疑服务。 </p> <p> <br> </p> <p class="ql-long-24357476"> 讲师介绍:裴帅帅,前百度资深架构师,现爱奇艺算法架构师全程亲自授课。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【为什么要学习这门套餐课?】 </p> <p class="ql-long-24357476"> Python无论是在web/爬虫/人工智能/大数据/机器学习/测试/运维/数据分析等等领域都有大量的应用,但是作为小白来讲,很难确定最适合自己的应用方向。 </p> <p> <br> </p> <p class="ql-long-24357476"> 在这门课程中,将带你从零入门Python,并向你讲授实战 Python 各个应用方向的核心知识点,同时应用于实战项目。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【学完后我将达到什么水平?】 </p> <p class="ql-long-24357476"> 你将能够熟练掌握 Python 在人工智能时代的多种技能,具备使用 Python 编写代码完成 Web 后台开发、网络爬虫、数据分析、机器学习、推荐系统等多种项目实战的能力,掌握 Python 全栈工程师的核心能力。 </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程学习路径】 </p> <p class="ql-long-24357476"> 本套课以市场就业和职位需求为核心,从 Python 入门到多领域实战,并结合 Python 全栈工程师的进阶路线,共分为八大模块,分别是:Python 基础、Python Web 开发、Python 爬虫、Numpy 数据计算、Pandas 数据分析、Python数据可视化、Tensorflow 深度学习、推荐系统实战应用模块。 </p> <p> <br> </p> <p class="ql-long-24357476"> 套餐中一共包含8门Python课程(共246讲)助你从零进阶Python全栈工程师! </p> <p class="ql-long-24357476"> 课程1:《Python零基础入门视频教程》 </p> <p class="ql-long-24357476"> 课程2:《Python爬虫从入门到实战》 </p> <p class="ql-long-24357476"> 课程3:《Python使用Flask开发Web服务》 </p> <p class="ql-long-24357476"> 课程4:《Python使用Numpy入门数据计算》 </p> <p class="ql-long-24357476"> 课程5:《Python使用Pandas入门数据分析》 </p> <p class="ql-long-24357476"> 课程6:《Python数据图表可视化》 </p> <p class="ql-long-24357476"> 课程7:《Tensorflow深度学习从入门到实战》 </p> <p class="ql-long-24357476"> 课程8:《推荐系统技术入门到实战》 </p> <p> <br> </p> <p class="ql-long-24357476"> 【面向人群】 </p> <p class="ql-long-24357476"> 1、在校计算机专业或者对软件编程感兴趣的学生; </p> <p class="ql-long-24357476"> 2、想要使用数据分析、网络爬虫提升职场竞争力升职加薪的各行各业的企业白领; </p> <p class="ql-long-24357476"> 3、想要转方向成为数据分析师、大数据开发、机器学习算法、推荐系统工程师的职场码农; </p> <p class="ql-long-24357476"> 4、准备从事人工智能、Python开发的程序员。 </p> </span> <p> <br> </p> <p class="ql-long-24357476"> <br> </p> <p> <br> </p> <p class="ql-long-24357476"> 【课程知识体系图】 </p> </span></span></span> <p> <img src="https://img-bss.csdnimg.cn/202006100818561687.png" alt=""> </p>

150讲轻松搞定Python网络爬虫

05-16
【为什么学爬虫?】        1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!        2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站 【课程设计】 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: 网络请求:模拟浏览器的行为从网上抓取数据。 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个节用来提高爬虫程序的灵活性,分别是: 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。   从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! 【课程服务】 专属付费社群+每周三讨论会+1v1答疑
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值