当前位置: 首页 > news >正文

C++lambda表达式深入解析

C++lambda表达式深入解析

lambda表达式是C++11引入的匿名函数特性,它提供了一种简洁的方式来定义内联函数对象,特别适合用于STL算法和回调函数。

lambda表达式的基本语法包括捕获列表、参数列表、返回类型和函数体。

#include
#include
#include
#include

void basic_lambda_syntax() {
auto simple = []() {
std::cout << "Simple lambda\n";
};
simple();

auto with_params = [](int x, int y) {
return x + y;
};
std::cout << "Sum: " << with_params(3, 4) << "\n";

auto with_return_type = [](int x) -> double {
return x * 1.5;
};
std::cout << "Result: " << with_return_type(10) << "\n";
}

捕获列表决定了lambda如何访问外部变量,可以按值捕获或按引用捕获。

void capture_examples() {
int x = 10;
int y = 20;

auto by_value = [x, y]() {
std::cout << "Captured by value: " << x << ", " << y << "\n";
};
by_value();

auto by_reference = [&x, &y]() {
x += 5;
y += 10;
std::cout << "Modified: " << x << ", " << y << "\n";
};
by_reference();
std::cout << "After lambda: " << x << ", " << y << "\n";

auto mixed = [x, &y]() {
std::cout << "Mixed capture: " << x << ", " << y << "\n";
};
mixed();

auto capture_all_by_value = [=]() {
std::cout << "All by value: " << x << ", " << y << "\n";
};
capture_all_by_value();

auto capture_all_by_ref = [&]() {
x *= 2;
y *= 2;
};
capture_all_by_ref();
std::cout << "After capture all: " << x << ", " << y << "\n";
}

mutable关键字允许lambda修改按值捕获的变量。

void mutable_lambda() {
int counter = 0;

auto increment = [counter]() mutable {
++counter;
std::cout << "Lambda counter: " << counter << "\n";
};

increment();
increment();
increment();
std::cout << "Original counter: " << counter << "\n";
}

lambda表达式在STL算法中非常有用,可以提供自定义的比较和操作逻辑。

void lambda_with_algorithms() {
std::vector numbers = {5, 2, 8, 1, 9, 3, 7, 4, 6};

std::sort(numbers.begin(), numbers.end(), [](int a, int b) {
return a > b;
});

std::cout << "Sorted descending: ";
for (int n : numbers) {
std::cout << n << " ";
}
std::cout << "\n";

auto it = std::find_if(numbers.begin(), numbers.end(), [](int n) {
return n > 5;
});
if (it != numbers.end()) {
std::cout << "First number > 5: " << *it << "\n";
}

int threshold = 5;
int count = std::count_if(numbers.begin(), numbers.end(), [threshold](int n) {
return n > threshold;
});
std::cout << "Count > " << threshold << ": " << count << "\n";

std::vector doubled;
std::transform(numbers.begin(), numbers.end(), std::back_inserter(doubled),
[](int n) { return n * 2; });

std::cout << "Doubled: ";
for (int n : doubled) {
std::cout << n << " ";
}
std::cout << "\n";
}

泛型lambda使用auto参数,可以接受任意类型的参数。

void generic_lambda() {
auto print = [](const auto& value) {
std::cout << value << "\n";
};

print(42);
print(3.14);
print("Hello");

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

std::cout << "Int sum: " << add(10, 20) << "\n";
std::cout << "Double sum: " << add(1.5, 2.5) << "\n";
std::cout << "String concat: " << add(std::string("Hello"), std::string(" World")) << "\n";
}

lambda表达式可以递归调用,但需要使用std::function。

void recursive_lambda() {
std::function factorial = [&factorial](int n) -> int {
return n <= 1 ? 1 : n * factorial(n - 1);
};

std::cout << "5! = " << factorial(5) << "\n";
std::cout << "10! = " << factorial(10) << "\n";

std::function fibonacci = [&fibonacci](int n) -> int {
return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
};

std::cout << "Fib(10) = " << fibonacci(10) << "\n";
}

立即调用的lambda表达式可以用于初始化复杂的常量。

void immediately_invoked_lambda() {
const int value = [](int x) {
int result = 0;
for (int i = 1; i <= x; ++i) {
result += i;
}
return result;
}(10);

std::cout << "Sum 1 to 10: " << value << "\n";

const auto config = []() {
struct Config {
int max_connections;
double timeout;
std::string host;
};
return Config{100, 30.0, "localhost"};
}();

std::cout << "Config: " << config.max_connections << ", "
<< config.timeout << ", " << config.host << "\n";
}

lambda表达式可以存储在变量中并作为参数传递。

class EventHandler {
std::vector> handlers_;

public:
void add_handler(std::function handler) {
handlers_.push_back(handler);
}

void trigger(int value) {
for (auto& handler : handlers_) {
handler(value);
}
}
};

void lambda_as_callback() {
EventHandler handler;

handler.add_handler([](int value) {
std::cout << "Handler 1: " << value << "\n";
});

handler.add_handler([](int value) {
std::cout << "Handler 2: " << value * 2 << "\n";
});

int multiplier = 3;
handler.add_handler([multiplier](int value) {
std::cout << "Handler 3: " << value * multiplier << "\n";
});

handler.trigger(10);
}

C++14引入了初始化捕获,允许在捕获列表中初始化新变量。

void init_capture() {
auto ptr = std::make_unique(42);

auto lambda = [p = std::move(ptr)]() {
std::cout << "Captured unique_ptr: " << *p << "\n";
};

lambda();

auto counter = [count = 0]() mutable {
return ++count;
};

std::cout << "Count: " << counter() << "\n";
std::cout << "Count: " << counter() << "\n";
std::cout << "Count: " << counter() << "\n";
}

lambda表达式可以用于实现延迟计算和惰性求值。

template
class Lazy {
mutable std::function computation_;
mutable bool computed_;
mutable T value_;

public:
explicit Lazy(std::function comp)
: computation_(comp), computed_(false) {}

const T& get() const {
if (!computed_) {
value_ = computation_();
computed_ = true;
}
return value_;
}
};

void lazy_evaluation() {
Lazy expensive_computation([]() {
std::cout << "Computing expensive value...\n";
return 42 * 42;
});

std::cout << "Lazy value created\n";
std::cout << "First access: " << expensive_computation.get() << "\n";
std::cout << "Second access: " << expensive_computation.get() << "\n";
}

lambda表达式的闭包类型是编译器生成的唯一类型。

void lambda_type_info() {
auto lambda1 = [](int x) { return x * 2; };
auto lambda2 = [](int x) { return x * 2; };

std::cout << "Lambda1 type: " << typeid(lambda1).name() << "\n";
std::cout << "Lambda2 type: " << typeid(lambda2).name() << "\n";

std::function func1 = lambda1;
std::function func2 = lambda2;

std::cout << "Both can be stored in std::function\n";
}

lambda表达式可以捕获this指针访问成员变量。

class Calculator {
int base_value_;

public:
explicit Calculator(int base) : base_value_(base) {}

auto get_adder() {
return [this](int x) {
return base_value_ + x;
};
}

auto get_multiplier() {
return [*this](int x) {
return base_value_ * x;
};
}
};

void lambda_capture_this() {
Calculator calc(10);

auto adder = calc.get_adder();
std::cout << "Add: " << adder(5) << "\n";

auto multiplier = calc.get_multiplier();
std::cout << "Multiply: " << multiplier(5) << "\n";
}

lambda表达式在并发编程中用于定义线程任务。

#include
#include

void lambda_with_threads() {
int shared_value = 0;
std::mutex mutex;

std::vector threads;

for (int i = 0; i < 5; ++i) {
threads.emplace_back([&shared_value, &mutex, i]() {
for (int j = 0; j < 100; ++j) {
std::lock_guard lock(mutex);
shared_value += i;
}
});
}

for (auto& t : threads) {
t.join();
}

std::cout << "Final shared value: " << shared_value << "\n";
}

lambda表达式是现代C++中不可或缺的特性,它使代码更加简洁和表达力更强。理解lambda的各种用法和特性对于编写高效的C++代码至关重要。

http://www.jsqmd.com/news/862521/

相关文章:

  • 别再为连线头疼了!STM32F4开发板ST-Link与USB-TTL保姆级接线图(附Keil MDK配置)
  • AI安全中的门控发布机制与能力验证实践
  • 别再只会用map了!C++ unordered_map从入门到实战避坑指南
  • 别再只算差异了!用Cytoscape给Hub Gene分析加个‘可视化Buff’(附脑网络实战图)
  • 从MaskFormer到MP-Former:手把手拆解Transformer解码器在分割中的三大关键演进
  • 从Bloodshed到Embarcadero:老牌轻量IDE Dev-C++还值得C++新手用吗?
  • Navicat密码忘了别慌!手把手教你用Java小工具找回(支持15/16版本)
  • 别再手动画图了!用Mermaid+Markdown在VSCode里5分钟搞定UML设计文档
  • 30天学会AI工程师|Day 30:30 天结束后,最重要的不是兴奋,而是知道下一步该怎么走
  • Sunshine游戏串流快速上手:3步搭建你的个人云游戏服务器
  • 【Midjourney印象派风格创作指南】:20年AI视觉专家亲授5大核心参数调优法,3步生成莫奈级画作
  • 射频系统性能隐形变量:频率合成器核心指标与工程实践全解析
  • C++const正确性实践
  • 数据结构存储与操作:从数组、链表到哈希表与树的性能权衡
  • 19个脉冲神经元实现汽车实时控制:极简SNN控制系统解析
  • DINOv3特征工程实战:构建可解释、可增量、可部署的CV数据科学工作流
  • ROS Noetic下,5分钟搞定Hector SLAM建图(附避坑指南与完整launch文件)
  • 基于Windows Defender遥测数据与机器学习预测恶意软件感染风险
  • ddddocr实战测评:除了字母数字,它还能识别哪些奇葩验证码?(含滑块、点选测试)
  • 从官方demo到真实项目:手把手教你定制uniapp uni-card卡片的样式与交互
  • Unity渐变透明实现原理与跨管线避坑指南
  • 告别Callback Hell!用Kotlin协程重构你的Android网络请求层(附完整代码)
  • DETR训练总找不到目标边界?手把手拆解Conditional DETR的cross-attention,教你精准定位
  • Midjourney V6宝丽来风格实战手册:从提示词结构、--style raw权重分配到CMYK色偏补偿,5大参数公式即刻复刻经典Polaroid质感
  • 构图不是靠感觉!用Fitts定律+格式塔原理验证的Midjourney 6大构图公式(附Python自动构图评分脚本)
  • VAE的隐空间为什么是‘连续’的?一个可视化实验带你理解它与普通自编码器的本质区别
  • 别再折腾超级密码了!2024年电信光猫改桥接,打这个电话最快(附完整话术)
  • RAA在OFDM-ISAC系统中的高精度感知与通信优化
  • 初创公司利用taotoken聚合能力快速原型验证多个ai创意
  • Medium作者收益预测模型:轻量可解释的写作价值评估系统