New Features in C++11 学习

一、for循环:

1.举例:

vector<int> ve = {0,1,2,3,4,5,6,7,8,9,};
for( auto &r : ve)
	r *= 2;

2.相当于:

for(auto beg = ve.begin(),end = ve.end();beg != end;++beg)
{
	auto &r = (*beg);
	r *= 2;
}


二、Lambda表达式:

1.结构:

[]()->{};

2.解释:

[]:一层一层往外捕获值。

[=]:按值进行捕获。

[&]:按引用进行捕获。

():参数

{}:函数体

mutable:表示可以在函数体中修改捕获的值。

3.举例:

void biggies(vector<string> &words,vector<string>::size_type sz,ostream &os = cout,char c = '' )
{
for_each(words.begin(),words.end(),[&,c](const string &s){os<<s<<c;});
for_each(words.begin(),words.end(),[=,&c](const string &s){os<<s<<c;});
}
multable的作用:

//如果不加mutable,则不可以修改捕获来的v1,以下代码编译不过
//size_t v1 = 42;
//auto f = [v1]() {return ++v1;};
//加mutable后,编译就可以通过了
size_t v1 = 42;
{
 size_t v1 = 42;
 auto f = [v1]() mutable {return ++v1;};
}

->的作用:

明确指明要返回的类型,如果不写,则编译器会推断返回的类型,但是出现if....else....语句的时候要小心,为了避免错误,最好写明返回类型。

Lambda表达式就是为了简化函数对象所用的,目前我所理解的,他有两个作用。

第一、简化函数对象,如果某个函数中需要用到一个函数对象,而这个函数对象在其他地方就不再需要使用了,此时用Lambda表达式可以简化代码,而不用再去定义一个函数。

第二、传参。例如在find_if函数中,第三个参数的函数对象只能有一个参数,此时如果想要对第三个函数对象传第二个参数的时候。就不能办到了(先撇去bind函数不说)


但是话又说回来了,如果一个函数对象在许多地方都使用到了,如果再写Lambda表达式则会让这个Lambda表达式在许多地方都使用,使得难易管理和复用性太差。

此时我们可以选择用函数对象,增加代码的复用性。

但是问题又来了,如果某个地方需要用到的这个函数对象只能传递限定的参数呢(比如find_if),函数对象如何满足?

此时可以采用bind函数。

void check_size(const string& s,string::size_type sz)
{
	return s.size >= sz;
}
auto wc = find_if( words.begin,words.end(),bind(check_size,_1,sz));

其中,_n相当于Lambda的()中的参数,sz相当于[]中的值。

注意,bind的参数中,第一个为函数对象的名称,后面的参数为函数对象的参数,并且参数顺序要与函数对象中的参数顺序一致!

如果想捕获一个引用的变量,例如以下例子:

ostream &print(ostream &os,const string &s,char c)
{
	return os<<s<<c;
}
for_each(words.begin(),words.end(),bind(print,os,_1,' ');

for_each中的bind这样写对吗?

其实是错误的。因为bind是传递的一个os的拷贝,而流对象是不能拷贝的。

此时我们应该用ref或cref函数进行包装。

代码如下:

for_each(words.begin(),words.end(),bind(print,ref(os),_1,' ');


三、emplace_back、emplace、emplace_front

1.先介绍emplace,他是构造一个对象的,这三个函数都是给容器用的。

2.举例:

看代码:

vector<Person> ve;   //Person类是一个我自己写的类,包括姓名和性别
ve.push_back("huang","male");    //这样是错误的,ve的数据类型是person
ve.emplace_back("huang","male");    //这样是可以的,因为emplace_back会先构造一个对象,然后再插入ve中

四、将一个函数申明为delete

1.解释:将一个函数申明为delete,表示该函数不可被用。

2.申明形式:void Function() = delete;

3.规则:

(1)如果构造函数或者是析构函数申明为delete,则不可以创建对象。

(2)如果拷贝构造函数被申明为delete,则对象之间不可以进行拷贝。

例如:iostream则不想让多个对象对同一个流进行操作,则此时可以将他的拷贝构造函数申明为delete,这样的话就不会发生拷贝了。

(3)拷贝构造函数有可能被编译器推测为delete的情况有:

1.该类中有一个成员变量,该成员变量的构造函数被申明为delete。

2.该类中有一个成员变量,该成员变量的析构函数被申明为delete。

3.该类中有一个成员变量,该成员变量为一个为被初始化的引用。

写到这里发现上面写的规则有点多余,其实本质上来说,只要是在类中的成员变量有不能被赋值,分配,销毁,则可能造成相应的

函数例如:构造函数、拷贝构造函数、operate = 、析构函数为delete(不可用)函数。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南窗客斯黄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值