《深入浅出c++11之6为改变思考方式而改变》

6 为改变思考方式而改变

6.1 指针空值–nullptr

C++ 98中,字面常量0的类型既可以是一个整型,也可以是一个无类型指针(void *)
C++ 11中,nullptr是一个所谓“指针空值类型”的常量。nullptr的类型是nullptr_t

nullptr类型数据所占用的内存空间大小跟void*相同,即
sizeof(nullptr_t) == sizeof(void*)

nullptr到任何指针转换是隐式的
int *py = nullptr;

6.2 =default 与 =deleted

=default显示指示编译器生成该函数(默认函数)的默认版本。
=delete删除拷贝构造函数的缺省版本的实例,一旦缺省版本被删除了,重载该函数也是非法的。

class ConvType {
public:
	ConvType(int i ) {};
	ConvType(char c) = delete; //删除char版本
};

void Func(ConvType ct) {}

Func('a') //无法通过编译
ConvType cc('a'); //无法通过编译
注意:如果注释掉//ConvType(char c) = delete; 是可以编译过的,隐式转换为int

应该避免explicit关键字和=delete合用。否则,
explicit ConvType(char c) = delete;
Func('a') //可以通过编译,会尝试隐式的将c转换成int

6.3 lambda函数

[capture] (parameters) mutable -> return-type {statement}
如:
auto totalChild = [](int x, int y)->int {return x + y;};
  • [capture]:捕捉列表。编译器根据该引出符判断接下来的代码是否是lambda函数。
    • [var]表示值传递方式捕捉变量var
    • [=]表示值传递方式捕捉所有父作用域的变量(包括this)
    • [&var]表示引用方式传递捕捉变量var
    • [&]表示引用传递捕捉所有父作用域的变量(包括this)
    • [this] 表示值传递方式捕捉当前的this指针
  • (parameters)参数列表,如果不需要参数传递,可以连同()一起省略
  • mutable: mutable修饰符。默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略
  • -> return-type:返回类型。不需要返回值的时候,可以连同->一起省略。在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
  • {statement}:函数体
极端情况下,C++11最为简略的lambda函数为:
[]{}

//以引用传递的方式捕获变量a和b,值传递方式捕捉其它所有变量
[=, &a, &b]

//以值传递的方式捕捉变量a和this,引用方式捕捉其它所有变量
[&, a, this]

//捕捉列表不允许变量重复传递,否则会导致编译失败
[=, a] //=已经以值传递方式捕捉所有变量,捕捉a重复
[&, &this] //&已经以引用传递方式捕捉所有变量,再捕捉this也是一种重复

lambda函数不能捕获非自动变量(如静态变量)
6.3.1 lambda与仿函数
class Functor {
public:
	int operator()(int x, int y) {return x + y;}
};

int main() {
	int girls = 3, boys = 4;
	Functor totalChild;
	return totalChild(5, 6); //totalChild是个对象,使用起来向函数
}

C++ 11标准的定义上可以发现:lambda的类型被定义为“闭包”的类,而每个lambda表达式则会产生一个闭包类型的临时对象(右值)。严格地讲,lamdba函数并非函数指针。不过c++11标准却允许lambda表达是向函数指针的转换,只要lambda函数没有捕捉任何变量。

auto totalChild = [](int x, int y)->int {return x + y;}
typedef int (*allChild)(int x, int y);
typedef int (*oneChild)(int x);

allChild p;
p = totalChild;
decltype(totalChild) totalPeople = p; //编译失败,指针无法转换为lambda

使用lambda代替仿函数应该满足以下一些条件:

  • 是局限于一个局部作用域中使用的代码逻辑
  • 这些代码逻辑是需要被作为参数传递
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值