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++代码至关重要。
