【现代程序设计】【homework-07】

C++11 中值得关注的几大变化

 

 

1.Lambda 表达式

Lambda表达式来源于函数式编程,说白就了就是在使用的地方定义函数,有的语言叫“闭包”,如果 lambda 函数没有传回值(例如 void ),其回返类型可被完全忽略。 定义在与 lambda 函数相同作用域的变量参考也可以被使用。这种的变量集合一般被称作 closure(闭包)。表达式的简单语法如下

 

char s[]="Hello World!";  int Uppercase = 0; //modified by the lambda   for_each(s, s+sizeof(s), [&Uppercase] (char c) 
{   if (isupper(c))    Uppercase++;    }); cout << Uppercase << " uppercase letters in: " << s <<endl; 
View Code

在传统的STL中for_each()
这个玩意最后那个参数需要一个“函数对象”,所谓函数对象,其实是一个class,这个class重载了operator(),于是这个对象可以像函数的式样的使用。实现一个函数对象并不容易,需要使用template,比如下面这个例子就是函数对象的简单例子(实际的实现远比这个复杂):

 

template <class T> 
class less { 
public:     bool operator()(const T&l, const T&r)const  {     return l < r;    } 
};
View Code

 

所以,C++引入Lambda的最主要原因就是1)可以定义匿名函数,2)编译器会把其转成函数对象。相信你会和我一样,会疑问为什么以前STL中的ptr_fun()这个函数对象不能用?(ptr_fun()就是把一个自然函数转成函数对象的)。原因是,ptr_fun() 的局限是其接收的自然函数只能有1或2个参数。

那么,除了方便外,为什么一定要使用Lambda呢?它比传统的函数或是函数对象有什么好处呢?我个人所理解的是,这种函数之年以叫“闭包”,就是因为其限制了别人的访问,更私有。也可以认为他是一次性的方法。Lambda表达式应该是简洁的,极私有的,为了更易的代码和更方便的编程。

 

2.自动类型推导 auto

在在这一节中,原文主要介绍了两个关键字 auto 和 deltype,示例如下

 

auto x=0; //x has type int because 0 is int
auto c='a'; //char
auto d=0.5; //double
auto national_debt=14400000000000LL;//long long

auto 最大的好处就是让代码简洁,尤其是那些模板类的声明,比如:STL中的容器的迭代子类型。

vector<int>::const_iterator ci = vi.begin();

可以变成:

auto ci = vi.begin();

模板这个特性让C++的代码变得很难读,不信你可以看看STL的源码,那是一个乱啊。使用auto必需一个初始化值,编译器可以通过这个初始化值推导出类型。因为auto是来简化模板类引入的代码难读的问题,如上面的示例,iteration这种类型就最适合用auto的,但是,我们不应该把其滥用。

比如下面的代码的可读性就降低了。因为,我不知道ProcessData返回什么?int? bool? 还是对象?或是别的什么?这让你后面的程序不知道怎么做。

 

auto obj = ProcessData(someVariables);

但是下面的程序就没有问题,因为pObject的型别在后面的new中有了。

 

auto pObject = new SomeType<OtherType>::SomeOtherType();

 

 

3.自动化推导 decltype

 

关于 decltype 是一个操作符,其可以评估括号内表达式的类型,其规则如下:

  1. 如果表达式e是一个变量,那么就是这个变量的类型。
  2. 如果表达式e是一个函数,那么就是这个函数返回值的类型。
  3. 如果不符合1和2,如果e是左值,类型为T,那么decltype(e)是T&;如果是右值,则是T。

原文给出的示例如下,我们可以看到,这个让的确我们的定义变量省了很多事。

1
2
3
const vector<int> vi;
typedef decltype (vi.begin()) CIT;
CIT another_const_iterator;

还有一个适合的用法是用来typedef函数指针,也会省很多事。比如:

 

decltype(&myfunc) pfunc = 0;
  
typedef decltype(&A::func1) type;
4.auto 和 decltype 的差别和关系

Wikipedia 上是这么说的(关于decltype的规则见上)

#include <vector>
  
int main()
{
    const std::vector<int> v(1);
    auto a = v[0];        // a 的类型是 int
    decltype(v[0]) b = 1; // b 的类型是 const int&, 因为函数的返回类型是
                          // std::vector<int>::operator[](size_type) const
    auto c = 0;           // c 的类型是 int
    auto d = c;           // d 的类型是 int
    decltype(c) e;        // e 的类型是 int, 因为 c 的类型是int
    decltype((c)) f = c;  // f 的类型是 int&, 因为 (c) 是左值
    decltype(0) g;        // g 的类型是 int, 因为 0 是右值
}
如果auto 和 decltype 在一起使用会是什么样子?能看下面的示例,下面这个示例也是引入decltype的一个原因——让C++有能力写一个 “ forwarding
function 模板”,
template< typename LHS, typename RHS>
  auto AddingFunc(const LHS &lhs, const RHS &rhs) -> decltype(lhs+rhs)
{return lhs + rhs;}
这个函数模板看起来相当费解,其用到了auto 和 decltype
来扩展了已有的模板技术的不足。怎么个不足呢?在上例中,我不知道AddingFunc会接收什么样类型的对象,这两个对象的 +
操作符返回的类型也不知道,老的模板函数无法定义AddingFunc返回值和这两个对象相加后的返回值匹配,所以,你可以使用上述的这种定义。
5.统一的初始化语法

 

 

C/C++的初始化的方法比较,C++ 11 用大括号统一了这些初始化的方法。

 

比如:POD的类型。

 

1
2
int arr[4]={0,1,2,3};
struct tm today={0};

 

关于POD相说两句,所谓POD就是Plain Old Data,当class/struct是极简的(trivial)、属于标准布局(standard-layout),以及他的所有非静态(non-static)成员都是POD时,会被视为POD。如:

 

1
2
3
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m

 

POD的初始化有点怪,比如上例,new A; 和new A(); 是不一样的,对于其内部的m,前者没有被初始化,后者被初始化了(不同 的编译器行为不一样,VC++和GCC不一样)。而非POD的初始化,则都会被初始化。

 

从这点可以看出,C/C++的初始化问题很奇怪,所以,在C++ 2011版中就做了统一。原文作者给出了如下的示例:

 

1
2
3
4
5
6
7
8
9
C c {0,0}; //C++11 only. 相当于: C c(0,0);
  
int* a = new int[3] { 1, 2, 0 }; /C++11 only
  
class X {
    int a[4];
    public:
        X() : a{1,2,3,4} {} //C++11, member array initializer
};

 

容器的初始化:

 

1
2
3
4
5
// C++11 container initializer
vector<string> vs={ "first", "second", "third"};
map singers =
{ {"Lady Gaga", "+1 (212) 555-7890"},
{"Beyonce Knowles", "+1 (212) 555-0987"}};

 

还支持像Java一样的成员初始化:

 

1
2
3
4
5
6
class C
{
   int a=7; //C++11 only
 public:
   C();
};

 

转载于:https://www.cnblogs.com/lightz/p/3417006.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/399985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Jfinal源码解析系列一

2019独角兽企业重金招聘Python工程师标准>>> 1 Jfinal的初始化入口 <filter><filter-name>jfinal</filter-name><filter-class>com.jfinal.core.JFinalFilter</filter-class><init-param><param-name>configClass</pa…

Pycharm(社区版) 创建Flask项目

https://blog.csdn.net/hold_on_/article/details/86651594

【MSP430G2553】图形化开发笔记(2) 系统时钟和低功耗模式

目录系统时钟概述BCS模块单元的基本构造时钟-概览介绍Basic User 模式Power User 模式1. 数控振荡器 DCO2. 出厂预校正频率3. 低频振荡器 VLO4. 内部匹配电容5. 延时启动6. 自动选择 MCLK 源7. 时钟输出8. 振荡器失效中断9. 中断事件处理函数10. 退出中断后的节能选项Registers…

alias命令

alias命令&#xff08;取别名之前先运行一下将要使用的别名&#xff0c;以免冲突&#xff09; alias语法&#xff1a;alias 自定义的命令真正的命令 1.使用which查看一个命令的完整命令&#xff0c;也可以查看绝对路径 2.‘alias’查看系统中所有别名&#xff1a; 3.应用 再使用…

奇怪的 加号

转载于:https://www.cnblogs.com/chuyu/p/3421237.html

Java反射机制:表单数据自动封装到JavaBean中【IT】

2019独角兽企业重金招聘Python工程师标准>>> (2010-07-09 19:50:18) 转载▼ 标签&#xff1a; it 分类&#xff1a; IT路人丁 利用Java的反射机制&#xff0c;模拟一个简单的Struts控制器ActionServlet时&#xff0c;为了将请求的表单数据自动封装到JavaBean中&…

媒体查询使用方法@media

https://blog.csdn.net/leaves_yu/article/details/79280389 Media Queries能在不同的条件下使用不同的样式&#xff0c;使页面在不同在终端设备下达到不同的渲染效果。前面简单的介绍了Media Queries如何引用到项目中&#xff0c;但Media Queries有其自己的使用规则。具体来说…

JavaScript实现接口的三种经典方式

1 /*2 接口:提供一种说明一个对象应该有哪些方法的手段3 js中有三种方式实现接口:4 1 注释描述接口5 2 属性检测接口6 3 鸭式辨型接口7 */8 9 /*10 1 注释描述接口&#xff1a; 不推荐11 优点&#xff1a; 利用注解&#xff0c;给出参考12 缺点&#x…

eclipse启动tomcat不能正常访问问题

问题&#xff1a; 1、eclipse中配置好tomcat服务器后&#xff0c;启动tomcat查看控制台信息显示启动成功&#xff0c; 但访问tomcat首页报404异常 2、而从tomcat/bin目录中启动后&#xff0c;就能够正常访问首页&#xff0c;由此分析应该是eclipse配置错误 解决方案&#xff1a…

AD域

将网络中的计算机逻辑上组织到一起&#xff0c;将器视为一个整体进行集中管理&#xff0c;这种区别于工作组的逻辑环境叫做Windows域。windows管理模式有两种&#xff1a;工作组和与环境。活动目录的相关概念(1)域和域控制器(2)名称空间(3)对象和属性(4)容器(5)组策略活动目录的…

人工智能领域2023年12月15日-12月24日大事件

时代在高速的发展&#xff0c;本文让你快速了解人工智能领域12月15日至12月24日大事件。 文章目录 1 全球AI芯片市场规模预计突破千亿美元2 AI在金融领域的应用取得重大突破3 AI在医疗领域取得重大突破4 全球首个AI教育平台正式发布5 全球首个AI驾驶执照颁发6 AI助力农业增产增…

pycharm如何汉化

https://blog.csdn.net/jia666666/article/details/81777017 我们将汉化包里面的resource_zh.jar文件放入pycharm安装目录lib文件下面即可。

Python学习笔记19(算法)

1.二分查找 只能用二分查找查找有序列表 def bin_search(data,val): #data为被查找的列表&#xff0c;val是要查找的值low 0high len(data) - 1while low < high:mid (lowhigh)//2if data[mid] val:return mid #找到了&#xff0c;返回val所在的索引elif dat…

C#通过接口与线程通信(捕获线程状态)介绍

摘要&#xff1a;本文介绍C#通过接口与线程通信(捕获线程状态)&#xff0c;并提供简单的示例代码供参考。 提示&#xff1a;本文所提到的线程状态变化&#xff0c;并不是指线程启动、暂停、停止&#xff0c;而是说线程内部状态的迁移。随着软件技术不断发展&#xff0c;用户需求…

php 类文件加载 Autoloader

做习惯了编译语言&#xff0c;转到php 使用 php的面向对象开发时候遇见一个挺别扭的问题。在Php中引入对象 后 在调用过程中还需要将对象所在的php文件 require 到当前php文件 目前代码结构 index.php <?phpuse model\BookModel;include_once __DIR__./autoloader.php; Aut…

【MSP430G2553】图形化开发笔记(4) Timer_A 定时器

目录概述Timer_A 模块16 位主定时器连续计数模式增计数模式增减计数模式主定时器的一般设置捕获/比较模块 CCRx捕获模块比较模块小结Grace中配置Timer_ATimer0_A3 - Overview介绍用例&#xff1a;定时器的启动/停止用例&#xff1a;使用定时器比较模式产生周期性间隔用例&#…

flask学习笔记--蓝图

https://blog.csdn.net/m0_37519490/article/details/80627601 初学者建议看 https://www.cnblogs.com/jackadam/p/8684148.html

前端UI框架《Angulr》入门

Angulr 项目的名称为 Angulr&#xff0c;对&#xff01;没错&#xff01;就是少个 a&#xff0c;少个 a 就是它正确的拼写。 是一个以 Bootstrap 和 AngularJS 为基础&#xff0c;并使用了大量前端开源组件合成的一个前端UI框架&#xff0c;是非常棒的UI框架。 今天就来和大家讲…

比赛一买香蕉问题---解题报告

买香蕉问题 题目大意&#xff1a; 士兵想买W个香蕉。买第一个香蕉K美元&#xff0c;第二个2K美元&#xff0c;以此类推&#xff0c;第i 个香蕉iK美元。 现在该士兵有n美元&#xff0c;而他想买W个香蕉&#xff0c;他需要向他的朋友借多少美元&#xff1f; 要求&#xff1a; 输入…

Flask使用Flask-SQLAlchemy操作MySQL数据库

https://www.jianshu.com/p/6ae0d30a5539 前言&#xff1a; Flask-SQLAlchemy是一个Flask扩展&#xff0c;简化了在Flask程序中使用SQLAlchemy的操作。SQLAlchemy是一个很强大的关系型数据库框架&#xff0c;支持多种数据库后台。SQLAlchemy提供了高层ORM&#xff0c;也提供了…