从零手写SLAM笔记



简单循环、自动类型推导、列表初始化

题目:请使用C++新特性改写以下函数。该函数功能:将一组无序的坐标按照“Z”字形排序,并输出。

题目如下图所示:

SLAM练习题(二)—— C++新特性:简化循环、自动类型推导、列表初始化、lambda函数_slam

知识点:熟悉C++新特性(简化循环、自动类型推导、列表初始化、lambda函数/*)

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
vector<Point2i> vec{
{2,1},{3,3},{2,3},{3, 2} ,{3, 1} ,{1, 3} ,{1, 1} ,{2, 2} ,{1, 2}
};
cout<<"Before sort:"<<endl;
for(auto v:vec) cout<<v<<endl;
sort(vec.begin(),vec.end(),
[=](Point2i pt1, Point2i pt2)->bool {return(
pt1.x<pt2.x)?(1):(pt1.x==pt2.x && pt1.y<pt2.y); //妙啊 三元表达式?
}); //使用了lambda函数
cout<<"After sort:"<<endl;
for(auto v:vec) cout<<v<<endl;
return 0;
}

附:CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

project(003_practice)

set(CMAKE_CXX_FLAGS "-std=c++11")

# OpenCV
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_DIRS})

add_executable(my_sort my_sort.cpp)
target_link_libraries(my_sort ${OpenCV_LIBS})
lambda函数

​参考​

[捕捉列表] (参数) mutable -> 返回值类型 {函数体}

说明:

  • []是lambda的引出符,捕捉列表能够捕捉上下文中的变量,来供lambda函数使用:

[var] 表示以值传递方式捕捉变量var

[=] 表示值传递捕捉所有父作用域变量

[&var] 表示以引用传递方式捕捉变量var

[&] 表示引用传递捕捉所有父作用域变量

[this] 表示值传递方式捕捉当前的this指针

还有一些组合:

[=,&a] 表示以引用传递方式捕捉a,值传递方式捕捉其他变量

注意:

捕捉列表不允许变量重复传递,如:[=,a]、[&,&this],会引起编译时期的错误


  • 参数列表与普通函数的参数列表一致。如果不需要传递参数,可以联连同()一同【省略】。
  • mutable 可以取消Lambda的常量属性,因为Lambda默认是const属性;multable仅仅是让Lamdba函数体修改值传递的变量,但是修改后并不会影响外部的变量。
  • ->返回类型如果是void时,可以连->一起【省略】,如果返回类型很明确,可以省略,让编译器自动推倒类型。
  • 函数体和普通函数一样,除了可以使用参数之外,还可以使用捕获的变量。

sort()函数

​参考​

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp); 

(1)第一个参数first:是要排序的数组的起始地址。

(2)第二个参数last:是结束的地址(最后一个数据的后一个数据的地址)

(3)第三个参数comp是排序的方法:可以是从升序也可是降序。如果第三个参数不写,则默认的排序方法是从小到大排序。

要注意的是第三个参数comp, 用户自己提供一种排序的方法,当该方法返回true时,比较的两个点位置不变,返回flase时,两个点交换位置。

上面提供的比较方法还可以写成如下形式:

sort(vec.begin(), vec.end(),
[](Point2i a, Point2i b)-> bool

{
if(a.x < b.x) return true;// 按横坐标从小到大排序
if(a.x == b.x)
{
return a.y < b.y;// 当横坐标一致时,按纵坐标从小到大排序
}
return false;
});