Caro的代码使用了大量的 C++11 新特性,这篇博客将对这些出现的特性进行汇总以及记录,我还没怎么用过C++11。

1 关键字:

constexpr: 在编译过程就能确定的常量(计算结果的表达式)

void Run() {constexpr double kTfBufferCacheTimeInSeconds = 10.;tf2_ros::Buffer tf_buffer{::ros::Duration(kTfBufferCacheTimeInSeconds)};tf2_ros::TransformListener tf(tf_buffer);// ...
}

delete: 禁止使用该函数

// Wires up ROS topics to SLAM. 将ROS主题连接到SLAM。
class Node {public:Node(const NodeOptions& node_options,std::unique_ptr<cartographer::mapping::MapBuilderInterface> map_builder,tf2_ros::Buffer* tf_buffer);~Node();// = delete 禁止使用该函数, delete 可用于任何函数Node(const Node&) = delete;Node& operator=(const Node&) = delete;// ...
}

explicit: 阻止隐式转换的发生

class SensorBridge {public:explicit SensorBridge(int num_subdivisions_per_laser_scan, const std::string& tracking_frame,double lookup_transform_timeout_sec, tf2_ros::Buffer* tf_buffer,::cartographer::mapping::TrajectoryBuilderInterface* trajectory_builder);// ...
}

2 用到的C++11的标准函数:

std::move(): 将左值引用转变为右值引用

void Run() {// ...// move() 将左值引用转变为右值引用auto map_builder =cartographer::common::make_unique<cartographer::mapping::MapBuilder>(node_options.map_builder_options);Node node(node_options, std::move(map_builder), &tf_buffer);if (!FLAGS_load_state_filename.empty()) {node.LoadState(FLAGS_load_state_filename, FLAGS_load_frozen_state);}// ...
}

std::tie()

void Run() {// ...NodeOptions node_options;TrajectoryOptions trajectory_options;std::tie(node_options, trajectory_options) =LoadOptions(FLAGS_configuration_directory, FLAGS_configuration_basename);// ...
}

std::forward_as_tuple()

  extrapolators_.emplace(std::piecewise_construct, std::forward_as_tuple(trajectory_id),std::forward_as_tuple(::cartographer::common::FromSeconds(kExtrapolationEstimationTimeSec),gravity_time_constant));

std::tuple()

set::insert()

std::unique_ptr<>

#include <memory>

std::mt19937 rng(0);

计算随机数的算法

std::prev

std::exp(),std::hypot(),std::abs()

    candidate.score *=std::exp(-common::Pow2(std::hypot(candidate.x, candidate.y) *options_.translation_delta_cost_weight() +std::abs(candidate.orientation) *options_.rotation_delta_cost_weight()));

std::max_element() , std::max()

  const Candidate2D& best_candidate =*std::max_element(candidates.begin(), candidates.end());// A possible solution.
struct Candidate2D {Candidate2D(const int init_scan_index, const int init_x_index_offset,const int init_y_index_offset,const SearchParameters& search_parameters): scan_index(init_scan_index),x_index_offset(init_x_index_offset),y_index_offset(init_y_index_offset),x(-y_index_offset * search_parameters.resolution),y(-x_index_offset * search_parameters.resolution),orientation((scan_index - search_parameters.num_angular_perturbations) *search_parameters.angular_perturbation_step_size) {}// Index into the rotated scans vector.int scan_index = 0;// Linear offset from the initial pose.int x_index_offset = 0;int y_index_offset = 0;// Pose of this Candidate2D relative to the initial pose.double x = 0.;double y = 0.;double orientation = 0.;// Score, higher is better.float score = 0.f;bool operator<(const Candidate2D& other) const { return score < other.score; }bool operator>(const Candidate2D& other) const { return score > other.score; }
};

std::sort() , std::greater

std::sort(candidates->begin(), candidates->end(), std::greater<Candidate2D>());

std::bind std::placeholders  : 占位符

  const int trajectory_id = map_builder_->AddTrajectoryBuilder(expected_sensor_ids, trajectory_options.trajectory_builder_options,::std::bind(&MapBuilderBridge::OnLocalSlamResult, this,::std::placeholders::_1, ::std::placeholders::_2,::std::placeholders::_3, ::std::placeholders::_4,::std::placeholders::_5));

std::function

// cartographer/cartographer/mapping/trajectory_builder_interface.h#include<functional>using LocalSlamResultCallback =std::function<void(int /* trajectory ID */, common::Time,transform::Rigid3d /* local pose estimate */,sensor::RangeData /* in local frame */,std::unique_ptr<const InsertionResult>)>;// cartographer/cartographer/mapping/map_builder_interface.husing LocalSlamResultCallback =TrajectoryBuilderInterface::LocalSlamResultCallback;// Creates a new trajectory builder and returns its index.virtual int AddTrajectoryBuilder(const std::set<SensorId>& expected_sensor_ids,const proto::TrajectoryBuilderOptions& trajectory_options,LocalSlamResultCallback local_slam_result_callback) = 0;// cartographer/cartographer/mapping/map_builder.hint AddTrajectoryBuilder(const std::set<SensorId> &expected_sensor_ids,const proto::TrajectoryBuilderOptions &trajectory_options,LocalSlamResultCallback local_slam_result_callback) override;

范围for循环:for (const auto& entry : sensor_bridges_)

std::unordered_map<int, MapBuilderBridge::TrajectoryState>
MapBuilderBridge::GetTrajectoryStates() {std::unordered_map<int, TrajectoryState> trajectory_states;for (const auto& entry : sensor_bridges_) {const int trajectory_id = entry.first;const SensorBridge& sensor_bridge = *entry.second;std::shared_ptr<const TrajectoryState::LocalSlamData> local_slam_data;{cartographer::common::MutexLocker lock(&mutex_);if (trajectory_state_data_.count(trajectory_id) == 0) {continue;}local_slam_data = trajectory_state_data_.at(trajectory_id);}// Make sure there is a trajectory with 'trajectory_id'.CHECK_EQ(trajectory_options_.count(trajectory_id), 1);trajectory_states[trajectory_id] = {local_slam_data,map_builder_->pose_graph()->GetLocalToGlobalTransform(trajectory_id),sensor_bridge.tf_bridge().LookupToTracking(local_slam_data->time,trajectory_options_[trajectory_id].published_frame),trajectory_options_[trajectory_id]};}return trajectory_states;
}// -----------const int half_width = 1 << (7 - 1);
for (int x_offset : {0, half_width})
{cout << x_offset << endl;
}

std::chrono

#include <chrono>// Time at which we last logged the rates of incoming sensor data.std::chrono::steady_clock::time_point last_logging_time_;

3 容器类相关

3.1 vector

reserve() , emplace_back() , push_back() , back()

std::vector<DiscreteScan2D> DiscretizeScans(const MapLimits& map_limits, const std::vector<sensor::PointCloud>& scans,const Eigen::Translation2f& initial_translation) {std::vector<DiscreteScan2D> discrete_scans;discrete_scans.reserve(scans.size());for (const sensor::PointCloud& scan : scans) {discrete_scans.emplace_back();discrete_scans.back().reserve(scan.size());for (const Eigen::Vector3f& point : scan) {const Eigen::Vector2f translated_point =Eigen::Affine2f(initial_translation) * point.head<2>();discrete_scans.back().push_back(map_limits.GetCellIndex(translated_point));}}return discrete_scans;
}

3.2 map

std::map()

#include <map>
#include <unordered_map>// These are keyed with 'trajectory_id'.std::map<int, ::cartographer::mapping::PoseExtrapolator> extrapolators_;std::unordered_map<int, TrajectorySensorSamplers> sensor_samplers_;

map::emplace() 用于直接构造和插入元素

3.3 set

std::set<>

  #include <set>  #include <unordered_set>// Adds a trajectory for offline processing, i.e. not listening to topics.int AddOfflineTrajectory(const std::set<cartographer::mapping::TrajectoryBuilderInterface::SensorId>&expected_sensor_ids,const TrajectoryOptions& options);// unordered_setstd::unordered_set<std::string> subscribed_topics_;

4 其他:

GUARDED_BY()

  MapBuilderBridge map_builder_bridge_ GUARDED_BY(mutex_);

EXCLUDES()

  std::unordered_map<int, TrajectoryState> GetTrajectoryStates() EXCLUDES(mutex_);

type_traits: 模板元编程

#include <cstddef>
#include <memory>
#include <type_traits>
#include <utility>// Implementation of c++14's std::make_unique, taken from
// https://isocpp.org/files/papers/N3656.txt
template <class T>
struct _Unique_if {typedef std::unique_ptr<T> _Single_object;
};

... : 可变参数模板

template <class T, class... Args>
typename _Unique_if<T>::_Single_object make_unique(Args&&... args) {return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

std::remove_extent: 返回数组降低一个维度后的数据类型

template <class T>
typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {typedef typename std::remove_extent<T>::type U;return std::unique_ptr<T>(new U[n]());
}

lamda表达式

// cartographer/mapping/internal/collated_trajectory_builder.ccsensor_collator_->AddTrajectory(trajectory_id, expected_sensor_id_strings,[this](const std::string& sensor_id, std::unique_ptr<sensor::Data> data) {HandleCollatedSensorData(sensor_id, std::move(data));});// cartographer/sensor/collator_interface.h// Adds a trajectory to produce sorted sensor output for. Calls 'callback'// for each collated sensor data.virtual void AddTrajectory(int trajectory_id,const std::unordered_set<std::string>& expected_sensor_ids,const Callback& callback) = 0;// cartographer/sensor/internal/collator.ccvoid Collator::AddTrajectory(const int trajectory_id,const std::unordered_set<std::string>& expected_sensor_ids,const Callback& callback) {for (const auto& sensor_id : expected_sensor_ids) {const auto queue_key = QueueKey{trajectory_id, sensor_id};queue_.AddQueue(queue_key,[callback, sensor_id](std::unique_ptr<Data> data) {callback(sensor_id, std::move(data));});queue_keys_[trajectory_id].push_back(queue_key);}
}// cartographer/sensor/internal/ordered_multi_queue.ccvoid OrderedMultiQueue::AddQueue(const QueueKey& queue_key, Callback callback) {CHECK_EQ(queues_.count(queue_key), 0);queues_[queue_key].callback = std::move(callback);
}

5 math.h

#include <cmath>
#include <vector>#include "Eigen/Core"
#include "cartographer/common/port.h"
#include "ceres/ceres.h"namespace cartographer {
namespace common {// Clamps 'value' to be in the range ['min', 'max'].
template <typename T>
T Clamp(const T value, const T min, const T max) {if (value > max) {return max;}if (value < min) {return min;}return value;
}// Calculates 'base'^'exponent'.
template <typename T>
constexpr T Power(T base, int exponent) {return (exponent != 0) ? base * Power(base, exponent - 1) : T(1);
}// Calculates a^2.
template <typename T>
constexpr T Pow2(T a) {return Power(a, 2);
}// Converts from degrees to radians.
constexpr double DegToRad(double deg) { return M_PI * deg / 180.; }// Converts form radians to degrees.
constexpr double RadToDeg(double rad) { return 180. * rad / M_PI; }// Bring the 'difference' between two angles into [-pi; pi].
template <typename T>
T NormalizeAngleDifference(T difference) {const T kPi = T(M_PI);while (difference > kPi) difference -= 2. * kPi;while (difference < -kPi) difference += 2. * kPi;return difference;
}template <typename T>
T atan2(const Eigen::Matrix<T, 2, 1>& vector) {return ceres::atan2(vector.y(), vector.x());
}template <typename T>
inline void QuaternionProduct(const double* const z, const T* const w,T* const zw) {zw[0] = z[0] * w[0] - z[1] * w[1] - z[2] * w[2] - z[3] * w[3];zw[1] = z[0] * w[1] + z[1] * w[0] + z[2] * w[3] - z[3] * w[2];zw[2] = z[0] * w[2] - z[1] * w[3] + z[2] * w[0] + z[3] * w[1];zw[3] = z[0] * w[3] + z[1] * w[2] - z[2] * w[1] + z[3] * w[0];
}}  // namespace common
}  // namespace cartographer

cartographer探秘第五章之 Cartographer 所用到的 C++11 新特性相关推荐

  1. 【16章Java 9 10 11新特性】Java9 Java10 Java11新特性

    ❤写在前面 ❤博客主页:努力的小鳴人 ❤系列专栏:JavaSE超详总结

  2. 疯狂java讲义第五章课后习题答案

    1.编写一个学生类,提供name.age.gender.phone.address.cmail成员变量,且为每个成员变量提供 seter.geter方法.为学生类提供默认的构造器和带所有成员变量的构造 ...

  3. 尚硅谷Java入门视频教程第十七章——Java9Java10Java11新特性

    尚硅谷Java入门视频教程第十七章--Java9&Java10&Java11新特性 第17章:Java9&Java10&Java11新特性 17.1 Java 9 的新 ...

  4. Python金融大数据分析——第五章数据可视化(1)二维绘图

    目录 第五章 数据可视化 5.1 二维绘图 5.1.1 一维数据集 5.1.2 二维数据集 5.1.3绘制其他图表 5.1.3.1绘制散点图 5.1.3.2 直方图 5.1.3.3 箱型图 第五章 数 ...

  5. 《NodeJS开发指南》第五章微博实例开发总结

    所有文章搬运自我的个人主页:sheilasun.me <NodeJS开发指南>这本书用来NodeJS入门真是太好了,而且书的附录部分还讲到了闭包.this等JavaScript常用特性.第 ...

  6. 2017-2018-1 20179215 《从问题到程序》第五章

    <从问题到程序>第五章读书笔记  这章主要从五个方面介绍,分别为数值类型.函数和标准库函数.函数定义和程序的函数分解.c程序的结构与变量及预处理.主要是对函数整体的理解以及常用的规范进行说 ...

  7. javascript高级程序设计 学习笔记 第五章 上

      第五章   引用类型的值(对象)是引用类型的一个实例.在 ECMAScript 中,引用类型是一种数据结构, 用于将数据和功能组织在一起.它也常被称为类,但这种称呼并不妥当.尽管 ECMAScri ...

  8. 计算机系统中处理的图片可分为,第五章图像处理.doc

    第五章图像处理.doc 第五章 图像处理 一.单选题: 1.既有层次变化又有颜色变化的图像是________. A.彩色图 B.灰度图 C.二值图 2.只有层次变化,颜色不发生变化的图像是______ ...

  9. 计算机组成与系统结构第二版第5章,计算机组成与系统结构第五章答案.pdf

    计算机组成与系统结构第五章答案 第五章 指令系统 2. 简单回答下列问题. (参考答案略) (1)一条指令中应该明显或隐含地给出哪些信息? (2 )什么是"汇编"过程?什么是&qu ...

  10. 悟透delphi 第五章 包

    第五章包 我们在日常生活中会用到各式各样的包,钱包.公文包.背包.书包--,包里面都装有经常要用的东西.一旦你那天要出门远行,带上该带的包就可以了.不用再考虑包里面具体的东西,尽管包里有的东西用得着而 ...

最新文章

  1. 调查:中国内地受访者每年花约40天用于各种“等”
  2. 语言 提取列名_学习健明老师发布的R语言练习题的学习笔记(二)
  3. 笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-08 数据修改
  4. iOS:面向对象的思想使用sqlite数据库
  5. KVM虚拟机添加磁盘空间
  6. 软件就像大教堂:我们建造它们——然后祈祷
  7. ABP理论学习之Abp Session
  8. [Spark][Python]对HDFS 上的文件,采用绝对路径,来读取获得 RDD
  9. java面试突击第一季 github,Github上星标77.6K+Java面试突击版笔记在咸鱼被疯传,太香了...
  10. 13. PHP 表数据入口(table data gateway)
  11. python目录和文件的基本操作_Python常用的文件及文件路径、目录操作方法汇总介绍...
  12. Linux调试工具之readelf
  13. ADAMS搭建控制系统教程:偏心连杆机构的转速控制
  14. 世界500强面试题(经典)
  15. c#制作仿win7屏幕键盘之笔记
  16. 洛谷 P1653 猴子 解题报告
  17. 小明一家过桥_「小明一家人过桥问题」如何用编程解决?
  18. [网络性能测试学习笔记] 测试AX3 Pro WiFi6无线路由器的系统转发能力(硬件转发交换能力L23吞吐量,L47应用层能力-最大可支持设备用户数,并发连接数等)
  19. 如何使用云桌面系统提高涉密网络安全性与方便性
  20. 怎样记账简单明白,实用记账技巧

热门文章

  1. django应用之corsheaders[跨域设置]
  2. jxl读数据库数据生成xls 并下载
  3. 粉丝关注数据库表的设计
  4. POJ 1637 混合图欧拉回路
  5. Apache Mina的用法
  6. 身为程序员的我们......
  7. Tomcat—如何在Windows 7中修改Tomcat的端口号
  8. 【IntelliJ IDEA】idea导入项目只显示项目中的文件,不显示项目结构
  9. BigDecimal的保留位数和四舍五入的方法
  10. Ajax请求生成中文乱码问题