4. 类对象成员的类内初始化
class ClassName
{
public:
int x = 10; //C++11 之前是不允许的
};
5. lambda表达式与bind函数
lambda表达式是一个可以被调用的代码单元,相当于一个内联函数,有参数和返回值以及函数体。但是跟函数不同的是,lambda表达式可以定义在函数的内部,一个完整的lambda表达式具有如下形式:
[捕获列表](参数列表) mutable -> 返回类型 {函数体}
int x = 10;
int y = 20;
auto f = [x,&y](int a ,int b){++y;return a+b+x+y;};
cout<<f(1,2)<<endl; //34
cout<<y<<endl; //21
lambda可以省略参数列表(如果没有参数的话),可以省略返回类型,但是不能省略捕获部分与函数体部分,即使捕获列表为空,也要有一个空的[],lambda有两种捕获,一种是值捕获,一种是引用捕获。如果是值捕获那么lambda中获得的是捕获的变量的副本,如果是引用捕获则获得的是引用,可以在lambda内部修改引用的变量的值,如上x是值捕获,y是引用捕获,lambda中默认是值捕获,如果变量前面添加&则是引用捕获,另外lambda中还有两种形式的引用捕获,例如[=]表示值捕获所有可见的变量,而[&]则表示引用捕获所有可见变量。如果希望值捕获所有可见变量,但是又有个别变量采用引用捕获呢,[=,&x]表示值捕获所有可见变量,同时引用捕获x。而[&,x]则表示引用捕获所有可见变量,x采用值捕获的方式。
有关bind函数,在很多地方我们可以使用函数替换lambda表达式,毕竟如果很多地方需要用到同一个lambda表达式,而且这个lambda表达式比较长的话,将其定义成函数应该是最好的。对于没有捕获列表的lambda表达式我们可以直接使用函数替代,例如:
void main()
{
auto f=[](int x,int y){return x+y};
f();
}
我们可以用下面的方式替代:
int f(int x,int y)
{
return x+y;
}
void main()
{
f();
}
与上面的lambda是等价的,但是对于有捕获列表的lambda表达式应该怎么处理呢,例如:
void main()
{
int x = 10;
int y = 20;
auto f = [x,&y](int a ,int b){return a+b+x+y;}; //一个值捕获,一个引用捕获
f(33,44);
}
如果转换成函数的形式:
int x = 10;
int y = 20;
int f(int a,int b)
{
return a+bx+y;
}
void main()
{
f(33,44);
}
这是一种可行的方法,但是总不能把所有的捕获变量定义成全局变量吧。现在的关键问题是lambda的捕获表达式中的内容转换成函数不可行,C++11提供了bind函数来完成这样的操作。
#include <functional> //bind()
#include <iostream>
using namespace std;
using namespace std::placeholders; // _1,_2所在的命名空间
int f(int x,int y,int a,int b)
{
return a+b+x+y;
}
void main()
{
int x = 10;
int y = 20;
auto f_wrap = bind(f,x,y,_1,_2);
cout<<f_wrap(33,44)<<endl; // _1,_2是占位符,表示调用f_wrap的时候_1是第一个参数,_2是第二个参数。最终会被替换成调用 f(10,20,33,44)
}










