0%

C++11 新特性

1. for_each

对于一些collection(vector,list,set,map)可以对其中每个元素执行后面的函数;

1
2
3
auto lambda_echo = [](int i ) { std::cout << i << std::endl; };  
std::vector<int> col{20,24,37,42,23,45,37};
for_each(col,lambda_echo);

2. Transform

std::transform在指定的范围内应用于给定的操作,并将结果存储在指定的另一个范围内。要使用std::transform函数需要包含头文件。

以下是std::transform的两个声明,一个是对应于一元操作,一个是对应于二元操作:

1
2
3
4
5
6
7
8
template <class InputIterator, class OutputIterator, class UnaryOperation>
OutputIterator transform (InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperation op);

template <class InputIterator1, class InputIterator2,
class OutputIterator, class BinaryOperation>
OutputIterator transform (InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result,

对于一元操作,将op应用于[first1, last1)范围内的每个元素,并将每个操作返回的值存储在以result开头的范围内。给定的op将被连续调用last1-first1次。op可以是函数指针或函数对象或lambda表达式。

1
2
int op_increase(int i) {return (i + 5)};
std::transform(first1, last1, result, op_increase);

3. auto和decltype联合使用

考虑一个模板函数

1
2
3
4
5
template<typename U, typename V>
??? foo(U u, V v){
...
return u*v;
}

总之我要在这个函数做点事情,最后返回一个u*v类型的东西。返回类型该怎么写?
C++11引入了返回类型后置解决这个问题,
1
2
3
4
template<typename U, typename V>
auto foo(U u, V v) -> decltype(u*v){
return u*v;
}

4.枚举类

枚举类(“新的枚举”/“强类型的枚举”)主要用来解决传统的C++枚举的三个问题:

  • 传统C++枚举会被隐式转换为int,这在那些不应被转换为int的情况下可能导致错误
  • 传统C++枚举的每一枚举值在其作用域范围内都是可见的,容易导致名称冲突(同名冲突)
  • 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解、兼容性问题以及不可以进行前向声明

枚举类(enum)(“强类型枚举”)是强类型的,并且具有类域:

1
2
3
4
5
6
7
8
9
10
11
12
13
enum Alert { green, yellow, election, red }; // 传统枚举
enum class Color { red, blue }; // 新的具有类域和强类型的枚举类
// 它的枚举值在类的外部是不可直接访问的,需加“类名::”
// 不会被隐式转换成int
enum class TrafficLight { red, yellow, green };
Alert a = 7; // 错误,传统枚举不是强类型的,a没有数据类型
Color c = 7; // 错误,没有int到Color的隐式转换
int a2 = red; // 正确,Alert被隐式转换成int
// 在 C++98中是错误的,但是在C++11中正确的
int a3 = Alert::red;
int a4 = blue; // 错误,blue并没有在类域中
int a5 = Color::blue; // 错误,没有Color到int的默认转换
Color a6 = Color::blue; // 正确

正如上面的代码所展示的那样,传统的枚举可以照常工作,但是你现在可以通过提供一个类名来改善枚举的使用,使其成为一个强类型的具有类域的枚举。
同时,他可以保证枚举值所占的字节大小,枚举类的底层数据类型必须是有符号或无符号的整数类型(int/short/char等),默认情况下是int。
1
enum class Color : char { red, blue }; // 紧凑型表示(一个字节)

5. 类型转换

关于强制类型转换的问题,很多书都讨论过,写的最详细的是C++ 之父的《C++ 的设计和演化》。最好的解决方法就是不要使用C风格的强制类型转换,而是使用标准C++的类型转换符:static_cast, dynamic_cast。
标准C++中有四个类型转换符:static_cast、dynamic_cast、reinterpret_cast、 const_cast