啥是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表达式之一。
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_2d
和 tracking_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的[函数对象参数 ]与(操作符重载函数参数)了啊。
哦哦哦。