c++11 新特性

auto 和 for循环

1
2
3
4
5
6
7
std::vector<int> vec {1,2,3,4,5};
for (auto n :vec)
std::cout << n;

int arr[10] = { 1, 2, 3, 4, 5};
for (auto n : arr)
std::cout << n;

C++11的for使用方法简单了很多,但是上述对容器的遍历是只读的,也就是说遍历的值是不可修改的。

如果要修改遍历的值,需要将遍历的变量声明为引用类型:

1
2
3
4
5
6
7
8
9
std::vector<int> vec {1,2,3,4,5};
cout << "修改前" << endl;
for (auto& n :vec)
std::cout << n++;
cout << endl;

cout << "修改后" << endl;
for (auto j : vec)
std::cout << j;

结果:
1
2
3
4
修改前
12345
修改后
23456

lambda表达式

C++11提供了对匿名函数的支持,称为Lambda表达式. Lambda表达式具体形式如下:
[capture](parameters)->return-type{body}

如果没有参数,空的圆括号()可以省略。 返回值也可以省略,如果函数体只由一条return语句组成或返回类型为void的话。形如:
[capture](parameters){body}

几个Lambda函数的例子:     

1
2
3
4
[](int x, int y) { return x + y; } // 隐式返回类型
[](int& x) { ++x; } // 没有return语句 -> lambda 函数的返回类型是'void'
[]() { ++global_x; } // 没有参数, 仅访问某个全局变量
[]{ ++global_x; } // 与上一个相同,省略了()

先掌握这些简单的情况

判断inf, nan

1
2
3
4
5
bool isinf( float arg );

bool isfinite( float arg );

bool isnan( float arg );

constexpr

C++11新标准规定,允许将变量声明为constexpr类型以便由编译器验证变量的值是否是一个常量表达式。如果不是,编译器报错。同时,声明为constexpr的变量一定是常量,而且必须用常量表达式初始化。 constexpr可以修饰函数参数、函数返回值、变量、类的构造函数、函数模板等,是一种比const更加严格的约束,它修饰的表达式除了具有“运行时常量性”,也具有“编译时常量性”,即constexpr修饰的表达式的值在编译期间可知。

1
2
3
4
5
6
constexpr int mf = 20;              //正确,20是常量表达式
constexpr int limit = mf + 1; //正确,mf + 1是常量表达式
constexpr int sz = size(); //未知,若size()函数是一个constexpr函数时即正确,反之错误。

int i = 10;
constexpr int t = i; //错误,i不是常量

参考:constexpr

大括号初始化

在C++11中,自动变量和全局变量的初始化方式增加了几种:

1
2
3
int a = {3+4};
int a{6+8};
int a(6+8);

主要是大括号的用法,另外大括号内可以不包含任何内容,此时变量初始化为0
1
2
int roc = {};
int roc{};

STL也可以用大括号的方式初始化,比如 vector

1
vector<int> c{ 1, 2, 3 };

这显然不能从构造函数角度理解了,源于<initializer_list>头文件中initialize_list类模板的支持。只要#include<initializer_list>并声明一个以initialize_List<T>模板类为参数的构造函数,也可以使得自定义类使用列表初始化。

在C++11中,除了初始化列表(在构造函数中初始化)外,允许使用等=或花括号{}进行就地的非静态成员变量初始化,例如:

1
2
3
4
5
class example
{
int a = 1;
double b{ 1.2 };
};

如果在一个类中,既使用了就地初始化来初始化非静态成员变量,又在构造函数中使用了初始化列表,执行顺序是: 先执行就地初始化,然后执行初始化列表。

匿名命名空间

std::tie

限域枚举

1
2
3
4
5
6
7
8
enum class SensorType {
RANGE = 0,
IMU,
ODOMETRY,
FIXED_FRAME_POSE,
LANDMARK,
LOCAL_SLAM_RESULT
};

using

1
2
3
4
5
6
7
8
9
class MapBuilderInterface {
public:
using LocalSlamResultCallback =
TrajectoryBuilderInterface::LocalSlamResultCallback;

using SensorId = TrajectoryBuilderInterface::SensorId;

using Callback =
std::function<void(const std::string&, std::unique_ptr<Data>)>;

std::weak_ptr

std::weakptr Schedule(std::unique_ptr task)
LOCKS_EXCLUDED(mutex
) override;