cartographer的c++之lambda

文章介绍了lambda表达式在C++中的概念,通过实例展示了其如何在cartographer和ROS中作为一次性操作的工具,以及如何通过捕获列表和操作符重载处理额外参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

啥是lambda啊

lambda 是一种匿名函数的表达式,它在很多编程语言中都有支持。在C++中,lambda 表达式允许你定义一个匿名函数,通常用于一次性的、简单的操作。(chatGPT)

这就是一个简单的例子。

auto add = [](int a, int b) -> int {
    return a + b;
};

int result = add(3, 5);
 [&tf_publisher, &tf_buffer](const rosbag::MessageInstance& msg) {
          if (msg.isType<tf2_msgs::TFMessage>()) {
            if (FLAGS_use_bag_transforms) {
              const auto tf_message = msg.instantiate<tf2_msgs::TFMessage>();
              tf_publisher.publish(tf_message);

              for (const auto& transform : tf_message->transforms) {
                try {
                  // We need to keep 'tf_buffer' small because it becomes very
                  // inefficient otherwise. We make sure that tf_messages are
                  // published before any data messages, so that tf lookups
                  // always work.
                  tf_buffer.setTransform(transform, "unused_authority",
                                         msg.getTopic() == kTfStaticTopic);
                } catch (const tf2::TransformException& ex) {
                  LOG(WARNING) << ex.what();
                }
              }
            }
            // Tell 'PlayableBag' to filter the tf message since there is no
            // further use for it.
            return false;
          } else {
            return true;
          }

这一段是cartographer中lambda表达式之一。

这就像lambda的公式::
[函数对象参数 = & ] (操作符重载函数参数) mutable exception 声明 (-> 返回值类型) {函数体}
以下代码为例
int x = 10;
auto add_with_captured_variable = [&x](int a, int b) -> int {
    // 在 lambda 内部可以使用和修改 x
    x++;
    return a + b + x;
};

int result = add_with_captured_variable(3, 5);

[ ]里面就是函数对象参数(在这个例子中, [&x] 表示通过引用捕获外部变量 x,这样 lambda 表达式内部就可以修改 x 的值。如果使用 [=],则是通过值捕获,lambda 表达式内部不能修改 x 的值。)。(int a, int b)就是 操作符重载函数参数,然后->(指向)返回值int,{}中是函数体。
第二个例子:
[node, handler, trajectory_id, topic](const typename 
MessageType::ConstPtr& msg)
{
 (node->*handler)(trajectory_id, topic, msg);
}

[ ]中也是函数对象参数+(操作符重载函数参数)+{ }函数体。

第三个例子:

const Rigid3d tracking_to_local = [&] {
 // 是否将变换投影到平面上
 if 
(trajectory_data.trajectory_options.publish_frame_projected_to_2d) {
 return carto::transform::Embed3D(
 carto::transform::Project2D(tracking_to_local_3d));
 }
 return tracking_to_local_3d;
}();

[&]:lambda 表达式的捕获列表,表示以引用的方式捕获当前作用域的所有外部变量。

{ }:函数体

():使用 () 运算符立即执行 lambda 表达式,而不是将其保存为函数对象。这种方式有时被称为“立即调用的 lambda 表达式”或者“立即执行函数表达式(Immediately Invoked Function Expression,IIFE)”。

在上面的代码中,[&] {...}() 的结构就是一个 IIFE。这种用法通常用于需要执行一些初始化操作,而不想在后续代码中再引用这个 lambda 表达式的情况。通过立即执行 lambda,你可以避免在后续代码中使用这个 lambda 表达式,同时允许你执行一些一次性的操作。

这个 lambda 表达式没有操作符重载函数参数,而是使用了闭包(捕获列表 [&])来访问外部的变量。

具体来说,lambda 表达式定义了一个匿名函数,它根据一些条件返回不同的值。在 lambda 表达式内部,它访问了外部的变量 trajectory_data.trajectory_options.publish_frame_projected_to_2dtracking_to_local_3d。Lambda 表达式内部的逻辑检查了 trajectory_data.trajectory_options.publish_frame_projected_to_2d 的值,如果为真,则执行 carto::transform::Embed3D(carto::transform::Project2D(tracking_to_local_3d)),否则返回 tracking_to_local_3d

这个 lambda 表达式最终被立即执行,因为它后面跟着一对括号 (),这意味着它在声明后立即执行,而不是保存为函数对象。因此,const Rigid3d tracking_to_local 的值将根据 lambda 表达式的逻辑条件被初始化。(ChatGPT)。

还有一个问题cartographer咋用上了lambda啊。

[node, handler, trajectory_id, topic](const typename 
MessageType::ConstPtr& msg)
{
 (node->*handler)(trajectory_id, topic, msg);
}

在ROS中我们通常订阅数据,然后有回调函数处理,在cartographer中除了接受的数据,还要配合其他的参数来处理,这就用到了lambda的[函数对象参数 ]与(操作符重载函数参数)了啊。

哦哦哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值