[GeekBand] 探讨C++新标准之新语法——C++ 11~14

一、 可变参数模板(Variadic Templates)

在C++11中,出现了参数数目可变的模板,这部分在之前C++高级编程的时候就有学习到。

其实,在C中就有类似的设定。最常用的printf(),就是一个采用了一个…类型的可变参数。…类型的参数代表是一个参数组。

  1. int???sumi(int???c,???...)
    ??{
    ????va_list???ap;
  2. ????va_start(ap,??c);
  3. ????int???i;
  4. ????int???sum???=???c;
  5. ????c???=???va_arg(ap,??int);
  6. ????while??(0??!=??c)
    ??????{
  7. ????????sum???=???sum??+??c;
  8. ????????c???=???va_arg(ap,??int);
  9. ????}
  10. ????return???sum;
    ??}

    在C中的…参数可以用va_list,va_start,va_arg等宏定义进行操作,其中va_arg()代表取值并进行指针的偏移;这种方式要求参数的类型必须能够得知。对于上例,即给定了参数就是int型;对于printf,则是通过一个字符串参数确定了有多少个变量。

    那么在C++中的…称为Pack(包);正如之前在高级编程时介绍的一样,通常采用递归的方式进行参数调用。

  11. void?print()?{}??
  12. template?<?typename?T,?typename…?Types?>?void?print(const?T?&?firstArg,??
  13. ????const?Types?&?…args)?{??
  14. ????cout?<<?firstArg?<<?endll;??
  15. ????print(args…);??
  16. }??

    在这里和之前版本的Package不同,非常神奇的一点是,我们不再需要使用偏移量。也就是说,我们在使用的时候根本不需要知道Pack里边的参数类型是什么。

    在C++11中提出了一个新的数据类型tuple(元祖),就是利用了新的…实现的:

  17. template?<?typename?Head,?typename...Tail?>?class?tuple?<?Head,?Tail...?>?:?private?tuple?<?Tail...?>?{??
  18. ????typedef?tuple?<?Tail...?>?inherited;??
  19. ????public:?
  20. tuple()?{}??
  21. ????tuple(Head,?Tail...vtail):?m_head(v),?inherited(vtail...)?{}??
  22. ????typename?Head::type?head()?{??
  23. ????????return?m_head;??
  24. ????}??
  25. ????inherited?&?tail()?{??
  26. ????????return?*this;??
  27. ????}??
  28. ????protected:?
  29. Head?m_head;??
  30. };??

    这个用法又非常的巧妙,Tuple继承自比自己少了Head参数的Tuple,如下图中的类图:

    二、 两个新的关键字nullptr & auto

    1. nullptr

    nullptr对象是一个空的指针,类型是nullptr_t;在C++11之前,一直是使用0(NULL就是0的一种宏定义)来代表空指针。在C++11中引入了nullptr,这一方面提高了代码可读性,另一方面使fun(int)和fun(void*)这种重载成为可能;

    2. auto

    自动推导返回值类型,编译器本身是有类型检查的功能的。C++11的auto就是在类型检查的时候才决定到底是什么类型,而不是像之前的编译器,检查左右是否一致。

    建议是指使用在类型特别长或者特别难写的情况,否则会降低可读性。

    还有一种情况是lambda表达式经常使用auto关键字

  31. auto??I??=???[](int??x)->??bool??{??/*…*/?}????

    三、 初始化列表

    1.通用初始化方法

    在之前,初始化的时候如果调用构造函数,则要使用小括号;如果是创建对象数组,则要使用大括号。而在C++11中,我们可以使用大括号进行所有的初始化操作,包括诸如int values[] {1,2,3}及complex<double> c{4,3} [等价于c(4,3)].其内部时进行了一个Initializer List的转化,关于initializer list的信息见下一节。

    必须提出的是,作为数组进行初始化时,大括号中的参数是一个一个传给变量进行初始化的,并不能提供多个的初始化。

    2.std::initializer_list<>

  32. #include?<?iostream?>?
  33. #include?<?stdio.h?>?
  34. #include?<?algorithm?>?
  35. #include?<?functional?>?
  36. using?namespace?std;??
  37. class?Print:?public?binary_function?<??
  38. ????const?char?*?,?int,?void?>?{??
  39. ????????public:?void?operator()(const?char?*?p,?int?a)?const?{??
  40. ????????????cout?<<?a?<<?‘?‘;??
  41. ????????}??
  42. ????};??
  43. class?P?{??
  44. ????public:?P(int?a,?int?b)?{??
  45. ????????cout?<<?"P(int,int),a="?<<?a?<<?",b="?<<?b?<<?endl;??
  46. ????}??
  47. ????P(initializer_list?<?int?>?initlist)?{??
  48. ????????cout?<<?"P(initializer_list<int>),values=?";??
  49. ????????for_each(initlist.begin(),?initlist.end(),?bind1st(Print(),?"%d?"));??
  50. ????????cout?<<?endl;??
  51. ????}??
  52. };??
  53. int?main()?{??
  54. ????P?p?{??
  55. ????????77,?5??
  56. ????};??
  57. ????P?q(77,?5);??
  58. }??

    创建p时会适配到初始化列表为参数;而创建q时则会适配到以两个int为参数。注意即使没有initializer_list版本的构造器,编译一样可以通过,因为发生了initializer_list的自动类型转换。

    3.initializer_list源码分析

    template<class _E>

    class initializer_list

    {

    const _E* __array;

    size_t __len;

    // The compiler can call a private constructor.

    initializer_list(const _E* __a, size_t __l)

    : __array(__a), __len(__l) { }

    public:

    initializer_list()

    时间: 2024-11-10 14:57:20

[GeekBand] 探讨C++新标准之新语法——C++ 11~14的相关文章

C99标准的新特性

C语言标准的发展 C语言的发展历史大致上分为4个阶段:Old Style C.C89.C99和C11. C89是最早的C语言规范,于1989年提出,1990年先由ANSI(美国国家标准委员会,American National Standards Institute)推出ANSI版本,后来被接纳为ISO国际标准(ISO/IEC9899:1990),因而有时也称为C90,最经典的C语言教材[K&R]就是基于这个版本的,C89是目前最广泛采用的C语言标准,大多数编译器都完全支持C89,C99(ISO

关注C++细节——C++11新标准之decltype的使用注意

c++11新特性--decltype decltype是C++11添加的一个新的关键字,目的是选择并返回操作数的数据类型,重要的是,在此过程中编译器分析表达式并得到它的类型,却不实际计算表达式的值. 对于内置类型的对象,使用decltype很直观,但当参数为复合类型的时候就应该注意一些使用细节问题. 1.当decltype作用于数组的时候就应该小心了,本文作者(CSDN   iaccepted). intiarr[10] = {0}; decltype(iarr)ib; 这个时候ib的定义等价于

《Javascript权威指南》学习笔记之十九--HTML5 DOM新标准---处理文档元信息和管理交互能力

一.了解DOM 1.DOM是Document Object Model的缩写,即文档对象类型,是文档在内存中的表示形式,是一个应用程序接口,定义了文档的逻辑结构以及一套访问和处理文档的方法. 2.HTML DOM与Core DOM的区别:前者提供了大量的方法和属性,与现有的程序模型一致,更便于脚本的编写者控制. 二.document对象 使用window.document属性返回一个document对象,代表当前window内加载的文档.window可以省略.winName.document返回

C++11新标准:nullptr关键字

一.nullptr的意义 1.NULL在C中的定义 #define NULL (void*)0 2.NULL在C++中的定义 #ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif 3.为什么C++和C中NULL定义不一样呢? void foo(int a) { cout<<"This is int"<<endl; } void foo

道路运输车辆卫星定位系统标准符合性检测 ----新规则、新方法

道路运输车辆卫星定位系统标准符合性检测 ----新规则.新方法 全称叫道路运输车辆卫星定位系统标准符合性检测或道路运输车辆卫星定位系统标准符合性审查,口语(或简称)为过检.交通部过检.平台过检.平台测试等等,符合性审查分硬件和平台,硬件就是即是车载终端,平台即运营平台,平台分企业平台.政府平台,企业平台分经营性与非经营性平台,政府平台分市级平台与省级平台.在这里讨论的是平台符合性审查,而非硬件. 此博文只介绍2015年恢复检测之后,采取的新测试规则,新测试方法.关于符合性审查的更详细说明,请参看

C++11新标准:decltype关键字

一.decltype意义 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了).为了满足这一需求,C++11新标准引入了decltype类型说明符,它的作用是选择并返回操作数的数据类型,在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值. 二.decltype用法 1.基本用法 int getSize(); int main(void) { int tempA = 2; /*1.dclTempA为int*/ declty

C++11新标准:auto关键字

一.auto意义 编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型,然后要做到这一点并非那么容易.为了解决这个问题,C++11新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型. 二.auto用法 1.基本用法 int tempA = 1; int tempB = 2; /*1.正常推断auto为int,编译通过*/ auto autoTempA = tempA + tempB; /*2.正常推断auto为int,编译通过*/ auto

C++旧源码向新标准移植陷井(一)_局部栈变量的生命周期

之前在VC++6.0上面写了下面这样的代码: int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; //不重要的部分略过if (argc>1) {if (strcmp(argv[1],"createpcsstep") == 0) { CDlgCreateStepPcs dlg; dlg.DoModal(); break; } else if (strcmp(argv[1],"clea

P2P联合银行 如何打造行业安全新标准?

在中国互联网领域里,互联网金融的发展时间几乎堪称最短,但互联网金融对国计民生和互联网经济所起到的促进与推荐作用,却远远超过其他任何互联网业务分支.在今天,基于移动终端和移动互联网的并行发展,以及互联网金融在普通大众生活.工作等领域的普遍应用,目前的互联网金融正在进入全新的生活服务领域,并以其巨大的渗透力改变着大众生活. 除了习以为常的金融信贷业务之外,互联网金融在今天的局面已经延伸和扩展到更多领域,其中较为明显的有征信体系.互联网信用系统建设等系统工作,这些业务虽然基于互联网方式而展开,但其对于