0%

c++11的新特性(一)--让程序更简洁

以下描述的c++11的7个新特性有没有让程序更简洁?是值得深度思考的,在我看来新增加的语法糖,可能带来便利,但也会加深学习曲线,增加代码阅读的难度,当然更应该在实践中加深理解,理解设计的初衷。

1. lambda表达式

这个特性还是很有必要有,但我思考是为了增加函数式编程而加进来的。lambda表达式在这里的主要用途就是写闭包函数

2. auto关键字和decltype关键字

两个关键字的区别:auto是通过定义时推导,decltype是通过表达式推导;我认为在模板编程的时候很有用处,在参数未实例化之前
使用auto关键字来代替定义,等到编译时自行推导,代码简洁

3. 模板别名和模板默认参数

模板右括号,在c++11之前的模板编程中是需要空格的,模板别名的定义也由#define改成了用表达式来定义

4. 基于范围的for循环

基于范围的for循环,有一些细节:首先for循环偏向于开始时确定循环范围,这样不适合在中途删除容器的元素;
for(auto n : array) {
// 要注意临时变量的值类型和引用类型的使用
}
自定义类型时要定义begin和end函数

5. std::function和std::bind

std::function被成为可调用对象包装器,在std库中没有之前,一直使用的是boost库中的;而这一次在标准库可以直接
使用function和bind,在也不用到处定义函数指针而烦恼了。

6. 列表初始化

列表初始化的设计初衷是什么?为了统一的初始化?也许是的,就是为了初始化的统一,这里要注意的是聚合类型
才能使用列表初始化
聚合类型的定义:

* 普通数组
* 类且无自定义的构造函数
* 无基类无虚拟函数
* 无私有的或者保护的非静态数据成员
* 不能有直接初始化的非静态数据成员

7. tuple元组

不同类型的集合,这让我想起了lua中的table,当然还是有本质区别;

以下是上面六个特性的实例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

#include <iostream>
#include <vector>
#include <map>

struct Position {
int x;
int y;
// 列表初始化时不允许私有和保护成员
//private:
// int z;
// 列表初始化时不允许直接初始化的非静态数据成员
// int f = 100;

void Print() {
std::cout << "x:" << x << " y:" << y << std::endl;
}
};

class MessageHandle {

public:
bool Init() {
// 特性5 std::bind
m_handle.insert(std::make_pair(10, std::bind(&MessageHandle::ProcessPos1,this,std::placeholders::_1)));
m_handle.insert(std::make_pair(100,std::bind(&MessageHandle::ProcessPos2,this,std::placeholders::_1)));
return true;
}

void Handle(int code,Position& pos) {
auto it = m_handle.find(code);
if(it!=m_handle.end()) {
it->second(pos);
return;
}

std::cout << "code :" << code << " not found!" << std::endl;
}

private:
void ProcessPos1(Position& pos) {
pos.x *= 10;
pos.y *= 10;
}

void ProcessPos2(Position& pos) {
pos.x *= 100;
pos.y *= 100;
}

private:
// 特性3 模板的别名和std::function
using handler_t = std::function<void(Position& pos)>;
std::map<int,handler_t> m_handle;
};

int main() {

// 特性6 列表初始化
std::vector<int> arr = {10,12,8,22,9,99,37};

//特性1和特性2
// lambda表达式
auto count = std::count_if(arr.begin(),arr.end(),[](int x) { return x > 10;});
std::cout << "count :" << count << std::endl;

// 特性4 基于范围的for循环
for(auto& n : arr) {
std::cout << n << std::endl;
}

//特性6 统一的初始化方式
Position pos {100,99};
pos.Print();

MessageHandle handler;
handler.Init();
handler.Handle(10,pos);
pos.Print();

return 0;
}

编译命令:
g++ test.cpp -o test -std=c++11