c++11新特性

本文介绍了C++中的模板技术,如模板别名、模板模板参数、VariadicTemplates、异常处理机制(noexcept)、模板继承与重写(override/final)、decltype的用法、explicit关键字的应用、右值引用的优化以及C++11引入的lambdas和初始化列表。
摘要由CSDN通过智能技术生成

模版别名Alias Template 

template <typename T>//模版参数
using Vec=std::vector<T,MyAlloc<T>>;
Vec<int> coll;//调用

用抽象类型作为模版参数,但Container会报错,因此用模板模版参数,能够在一个模板类中接受一个模板参数,在模板类中取出这个模板参数

模板模板参数

template<typename T, template<class> class Container>//类模版作为参数
class XCIs{
private:
	Container<T> c;
public:
	XCIs(){
		for(long i = 0; i < size; ++i)
			c.insert(c.end(), T());
		...(上图中的实现)
	}
}

但是,XCIs<Mystring, vector> 会报错,因为vector模板容器需要两个模板参数(类型和分配器)

因此使用using:

template <typename T>
using Vec = std::vector<T, MyAlloc<T>>;

XCIs<Mystring,Vec> c1;//能够正常调用

Variadic Temples可变参数

Template <typename T,typename… Types>
Void printX(const T& firstArg,const Types&… args){
	Cout<<firstarg<<endl;
	Printf(args…);//递归调用
}
print(7.5,"hello",biset<16>(337),42); // 可以这么调用
cout <<sizeof...(args)<< endl; // 想知道参数包中有几个参数,可以用sizeof...(args)
例子1: print()参数类型与个数均不同

例子2:max()
 参数Type都相同,max()的实现方式

参数type不同,max()的实现方式 

例子3:对于第一个元素和最后一个元素处理的方式不同

 

 例子4:Tuple:递归继承

 

例子5:递归复合

 类型别名Type Alias(类似typedef)

typedef void (*func)(int,int);//11之前
using func=void(*)(int,int);//11之后
using value_type=T;

 关键字

Noexcep

异常一定要被处理,如果一个函数声明为noexcept就会把异常交给上一层调用。

最好是告诉C++(特别是vector):移动构造函数和移动赋值构造函数是noexcept的。因为vector要增长空间,增长空间有构造函数调用过程,如果不显示声明移动构造时noexcept的,编译器不敢调用。

Override(复写)

只应用到虚函数上面:帮助编译器检测子类重写父类的虚函数有没有写错。否则,编译器只会将错误的函数当成子类自己的函数.

Final(是最后一个类/函数,不可以再被继承/重写)

修饰类,表示被修饰的类不能够继承;

修饰虚函数,表示虚函数不能被重写

Decltype

主要是为泛型编程而设计,以解决泛型编程中,由于有些类型由模板参数决定,而难以(甚至不可能)表示之的问题。有点类似typeof

用法:

(1)用来申明一个返回类型
auto add(T1 x,T2 y) -> decltype(x+y);//编译器会自动找出一个表达式的类型
(2) 元编程

       可以根据具体对象得到其对象类型

map<string, float> coll;

decltype(coll)::value_type elem; // C++11

map<string, float> coll;

map<string, float>::value_type elem; // C++11之前
(3) 得到lambda表达式的类型
auto add = [](int x, int y){

     return x + y;

}

cout << decltype(add) << endl; //假设可以输出

 explicit

struct complex{
	int real, imag;
	complex(int re, int im = 0) : real(re), imag(im){}
	explicit complex operator+(const complex& x){
		return complex((real + x.real), (imag + x.imag));
	}
}

complex c1(2,3);
complex c2=c1+5;//将int型转化为complex型

11之前,用于一个参数的构造函数。有上面的代码,那么在执行complex c1(12, 5); complex c2 = c1 + 5;的时候,构造函数不用explicit修饰,则会把5变成一个复数类,但是如果用explicit修饰了,这两句代码就会报错。也就是,让编译器知道,用户希望只在显式调用构造函数的时候才会调用,其他时候不允许调用。

11之后,explicit可用在接受一个以上参数的构造函数。突破了一个参数的限制,阻止任意多个参数的构造函数的隐式调用。

=default, =delete 

如果自行定义了一个构造函数,那么编译器就不会给你一个默认的构造函数;

如果你强行加一个 =default,就可以重新获得并使用编译器给出的默认构造函数。

=default只可以用于构造函数,=delete可用于任何函数,给编译器说明禁止使用这个函数。

class Zoo{
public:
    Zoo(int i1,int i2):d1(i1),d2(i2){}
    Zoo()=default;//构造函数可以有多个
    Zoo(const Zoo& x):d1(x.d1),d2(x.d2){}
    //!Zoo(const Zoo&)=default;//拷贝构造函数只能有一个
    Zoo(Zoo&&)=default;
    Zoo& operator=(const Zoo& x){d1=x.d1;d2=x.d2;return *this;}
    //!Zoo& operator=(const Zoo&)=default;
    //!Zoo& operator=(const Zoo&&)=delete;
    //!void func1()=default;//default用于特殊函数之外的函数无意义,编译报错
    void func2()=delete;//编译不会报错,表示不想编译这个函数
    ~Zoo(){}=default;
private:
    int d1,d2;
};

用法:无拷贝构造/私人拷贝构造--》单件模式

 Lambdas表达式

[x,&x,…] (const T &x,…) [mutable throwSpec -> retType] {...}
[][]开头的就是lambdas表达式,叫做introducer,用于捕获lambdas表达式外的变量用到具体方法内,可以指定传值方法。如果是=,则方法内可以以值传递的方式捕获lambdas外的所有变量
()()放函数参数
mutablemutable关系到[]中的内容是否可被改写,用在传值上(写上mutable说明[]中的值可以在{}中进行修改),可选
throwSpecthrowSpec指定是否抛出异常,可选
retTyperetType指定返回类型,可选
{}{}中放具体的方法实现
调用定义出来的是一个对象,需要()来调用

 例子:

auto I=[]{
	std::cout<<”hello”<<std::endl;
}
I();//调用

 C++11引入lambdas表达式,允许定义一个匿名函数,这个匿名函数是inline的。可以定义在一些状态或者表达式中。下图中的auto就是一个functor的匿名类。lambdas无默认构造函数(所以在容器中指定sort方法的时候,需要调用该容器对应的lambda构造函数)。

Rvalue reference右值引用

左值:可以出现在operator=左侧

右值:只能出现在operator=右侧

右值引用可用于减少非必要的拷贝,右边是一个右值,左边能偷到右值资源,而不用拷贝动作

临时对象是一个右值。拷贝构造是个深拷贝。

当右值出现于operator=的右侧时,我们认为其对资源进行搬移而非拷贝是可以的,合理的,那么:

  1. 必须要有语法让我们在调用端告诉编译器,这里是个右值(move)
  2. 必须有语法让我们在被调用端写出一个专门处理右值的move assignment函数(移动构造)

 初始化列表initializer_list

如果类中提供一个以initializer_list为参数的构造函数,那么使用{}来进行初始化的时候就直接调用他;如果不提供,那么就会将{}中的内容进行拆解,拆解为一个一个的参数,然后调用和{}中元素个数相同参数个数的构造函数。 

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值