设为首页 加入收藏

TOP

C++11的新特性介绍
2018-04-17 09:07:51 】 浏览:102
Tags:特性 介绍

一、auto无法带走cv限制符

C++标准中,const和volatile被称为“cv限制符,cv-qualifier”,它们分别代表了变量的两种不同的属性“不变的”和“易变的”。C++11标准规定auto可以和cv限制符一起使用,但是声明为auto的变量不能从其初始化表达式中“带走”cv限制符。例如const auto a = 1; 如果我们声明auto b = a; 那么b的类型是int而非const int,这里的例外是引用和指针,如果我们声明auto & c = a; 那么c的类型是const int&,声明为引用的变量依然保持着与其引用的对象相同的属性。

相比之下,decltype则可以带走cv限制符,但如果是一个对象的定义中含有const或volatile限制符,使用decltype进行推导时,其成员不会继承const和volatile。举例说明,const int i=0; 那么decltype(i)是const int,而如果:

struct S { int i; };

const S a = {0};

那么decltype(a)的类型是const S,但是a.i的类型并不是const。

还需要注意的是类型定义时的冗余符号:

int *a;

auto * b = a;,这里b的类型是int *而不是int **,因为在auto声明中,*也可以是冗余的,而如果使用decltype:

decltype(a) *c = &a;//decltype(a) *c = a无法通过编译

c的类型是int **。

二、追踪返回类型

如果一个函数模板的返回类型依赖于实际的入口参数类型,那么该返回类型在模板实例化之前可能都无法确定,这样的话我们在定义该函数模板时就会遇到麻烦。你可能会想到使用decltype来解决下面这个问题:

template
  
   
decltype(t1+t2) Sum(T1 &t1, T2 &t2) {
    return t1 + t2;
}
  

这里的问题是显而易见的,编译期通常并不能预知未来,在推导decltype(t1+t2)的时候,t1和t2还都是未定义的。为了解决这个问题,C++11引入新的语法——追踪返回类型:

template
  
   
auto Sum(T1 &t1, T2 &t2) -> decltype(t1+t2) {
    return t1 + t2;
}
  

这里有一个有趣的例子:

int (*(*pf())())(){ return nullptr; }

auto pf1() -> auto(*)() -> int (*)(){
    return nullptr;
}

这里pf是函数指针的指针,而pf1,从右往左看,auto(*)()-> int (*)()是函数指针,auto pf1() -> ~,pf1显然是前面这一部分的指针,也是函数指针的指针,它们其实是等价的。

auto (*fp)() -> int与int(*fp)()是等价的。auto (&fr)() -> int与int(&fr)()也是等价的。

吐槽,有人说学了C++11再也不怕别人看懂我的代码了,所言非虚。

还记得之前的转发函数吗,之前我们只实现了没有返回值的转发函数,如果要实现有返回值的转发函数,但我们返回值的类型显然是由待转发的内容所决定的,这时候就需要追踪返回类型了:

template
  
   
auto Forwarding(T && t) -> decltype(ActualFunc(forward(t))){
    return ActualFunc(forward(t));
}
  

这样即使ActualFunc存在一些重载的返回值类型不同的版本也可以实现转发。

三、基于范围的for循环

这个不必多言,对于可确定的迭代范围(类实现了begin和end函数),并且迭代对象实现了++,--等操作符,就可以使用基于范围的for循环。

具体形式类似for(int &e : arr)这样,如果不需要改变e的值,可以去掉取引用符号。

四、unique_ptr, shared_ptr, 和weak_ptr

由废弃的auto_ptr发展而来。unique_ptr形如其名,与所指对象的内存紧密绑定,不能与其他unique_ptr类型的指针对象共享所指对象的内存。从实现上来讲,unique_ptr是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型,我们仅仅可以使用右值引用对unique_ptr进行构造,而且一旦构造成功,右值对象中的指针即被窃取。

shared_ptr同样形如其名,它允许多个该智能指针共享地拥有同一堆分配对象的内存。在实现上,shared_ptr使用了引用计数。可以通过reset方法来减少相应的引用计数。

weak_ptr稍微复杂一点,它可以指向shared_ptr指针指向的对象内存,但并不拥有该内存。而使用weak_ptr的成员lock,可以返回其所指内存的一个shared_ptr对象,若该shred_ptr无效则返回nullptr,这个特性可以用来判断shared_ptr的有效性。


编程开发网
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C和C++的区别 下一篇C++ Virtual关键字详解

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }