Lambda Expressions
Lambda क्या है?
Lambda expression एक छोटा, बिना नाम का function है जो ठीक वहीं लिखा जाता है जहाँ ज़रूरत हो। C++11 से पहले घटते क्रम में sort करने के लिए सिर्फ sort को देने के लिए अलग नाम वाला function लिखना पड़ता था। Lambda से नियम वहीं inline लिख देते हैं:
std::sort(marks.begin(), marks.end(), [](int a, int b) { return a > b; });Lambdas code छोटा करते हैं और logic को वहीं रखते हैं जहाँ वह इस्तेमाल होता है। Modern C++ में ये हर जगह हैं: STL algorithms, callbacks, threads और event handlers।
Syntax
[capture] (parameters) mutable -> return_type { body }| हिस्सा | अर्थ | ज़रूरी? |
|---|---|---|
[capture] | बाहर के कौन-से variables lambda इस्तेमाल कर सकता है | हाँ (खाली [] भी हो सकता है) |
(parameters) | Inputs, साधारण function की तरह | न हों तो optional |
mutable | Value से capture किए को बदलने की अनुमति | Optional |
-> return_type | साफ़ return type | Optional — आमतौर पर खुद निकलता है |
{ body } | Code | हाँ |
पहले उदाहरण
#include <iostream>
int main() {
auto greet = []() { std::cout << "Hello from a lambda!\n"; };
greet();
auto add = [](int a, int b) { return a + b; };
std::cout << "3 + 4 = " << add(3, 4) << "\n";
auto average = [](double total, int count) -> double {
return count == 0 ? 0.0 : total / count;
};
std::cout << "average = " << average(254, 3) << "\n";
// तुरंत call करना
std::cout << [](int x) { return x * x; }(9) << "\n";
return 0;
}auto इसलिए लिखा जाता है क्योंकि हर lambda का अपना अनोखा, बिना नाम का type होता है।
Capture list
Lambda बाहर के सिर्फ उन्हीं local variables को इस्तेमाल कर सकता है जिन्हें वह capture करे।
| Capture | अर्थ |
|---|---|
[] | कुछ capture नहीं |
[x] | x की copy (by value) |
[&x] | मूल x से जुड़ाव (by reference) |
[=] | Body में इस्तेमाल हर बाहरी variable की copy |
[&] | Body में इस्तेमाल हर बाहरी variable reference से |
[=, &total] | सबकी copy, पर total reference से |
[this] | मौजूदा object के members (class के अंदर) |
#include <iostream>
int main() {
int passMark = 33;
int count = 0;
auto isPass = [passMark](int m) { return m >= passMark; }; // copy
auto countOne = [&count]() { count++; }; // reference
passMark = 40; // lambda अब भी अपनी copy इस्तेमाल करता है: 33
std::cout << isPass(35) << "\n"; // 1 (35 >= 33)
countOne();
countOne();
std::cout << "count = " << count << "\n"; // 2
return 0;
}mutable lambdas
Value से capture किए variables lambda के अंदर read-only होते हैं। mutable lambda को *अपनी copy* बदलने देता है:
int n = 0;
auto next = [n]() mutable { return ++n; };
std::cout << next() << next() << next(); // 123
std::cout << " n = " << n; // n = 0 (मूल नहीं बदला)STL algorithms के साथ lambdas
Lambdas की असली ताक़त यहीं दिखती है।
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
struct Student { std::string name; int marks; };
int main() {
std::vector<Student> cls = {{"Aman", 78}, {"Priya", 91}, {"Ravi", 29}, {"Sara", 66}};
// marks के हिसाब से sort, सबसे ज़्यादा पहले
std::sort(cls.begin(), cls.end(),
[](const Student& a, const Student& b) { return a.marks > b.marks; });
// pass गिनो
int passMark = 33;
int passed = std::count_if(cls.begin(), cls.end(),
[passMark](const Student& s) { return s.marks >= passMark; });
// हर एक print करो
std::for_each(cls.begin(), cls.end(),
[](const Student& s) { std::cout << s.name << " " << s.marks << "\n"; });
std::cout << "Passed: " << passed << " of " << cls.size() << "\n";
// 70 से कम वाला पहला student
auto it = std::find_if(cls.begin(), cls.end(),
[](const Student& s) { return s.marks < 70; });
if (it != cls.end()) std::cout << "First below 70: " << it->name << "\n";
return 0;
}Generic lambdas (C++14)
Parameters में auto लिखें और lambda किसी भी type के साथ चलेगा:
auto maxOf = [](auto a, auto b) { return a > b ? a : b; };
std::cout << maxOf(3, 7) << " " << maxOf(2.5, 1.5) << " "
<< maxOf(std::string("abc"), std::string("abd")); // 7 2.5 abdLambdas रखना: auto vs std::function
auto f = [](int x) { ... };— सबसे तेज़; आमतौर पर यही लें।std::function<int(int)> f = ...;(header<functional>) — तब ज़रूरी जब एक ही variable या container में अलग-अलग lambdas रखने हों, जैसे operations का menu।
#include <functional>
#include <map>
std::map<char, std::function<int(int, int)>> ops = {
{'+', [](int a, int b) { return a + b; }},
{'-', [](int a, int b) { return a - b; }},
};
std::cout << ops['+'](8, 5); // 13आम गलतियाँ
- बाहरी variable को capture किए बिना इस्तेमाल करना — compile error "is not captured"।
- ऐसे lambda में local को reference से capture करना जो function लौटने के बाद चले (जैसे store करके बाद में call) — dangling reference।
[x]से बाद मेंxमें हुए बदलाव दिखने की उम्मीद करना।- Value से capture किए को बदलते समय
mutableभूलना — "assignment of read-only variable"। - 40 lines का lambda लिखना; इतना लंबा हो तो नाम वाला function बनाएँ।
10 marks vector<int> में रखें। Lambdas से: उन्हें घटते क्रम में sort करें, 60 से 80 के बीच वाले गिनें (limits value से capture करें), for_each में reference parameter से 33 से कम वाले हर mark में 5 grace marks जोड़ें, और नतीजा print करें।
सारांश
- Lambda inline, बिना नाम का function है:
[capture](params) { body }। - Captures:
[x]copy,[&x]reference,[=]सब copy,[&]सब reference। mutablelambda को अपनी by-value copies बदलने देता है।- Lambdas
sort,count_if,find_if,for_eachके लिए बढ़िया comparators और predicates हैं। autoसे रखें; अलग-अलग lambdas एक variable में रखने हों तोstd::function।
संबंधित: functions, STL algorithms, modern C++ features, sorting और searching।
अक्सर पूछे जाने वाले प्रश्न (FAQ)
C++ में lambda expression क्या है?
[](int a, int b) { return a > b; }। यह C++11 में आया और ज़्यादातर sort, count_if और for_each जैसे STL algorithms को दिया जाता है।C++ lambda में capture list क्या है?
[ ] के अंदर लिखी capture list तय करती है कि आसपास के scope के कौन-से variables lambda इस्तेमाल कर सकता है। [x] x की copy लेता है, [&x] मूल x से जुड़ता है, [=] इस्तेमाल होने वाले सब कुछ की copy, और [&] सब कुछ reference से। [] कुछ capture नहीं करता।Capture by value और capture by reference में क्या अंतर है?
[x]) lambda बनते समय की copy रखता है, इसलिए बाद में x में बदलाव नहीं दिखते और lambda मूल variable नहीं बदल सकता। Capture by reference ([&x]) मूल variable इस्तेमाल करता है, इसलिए बदलाव दिखते हैं और उसे बदल भी सकता है — पर lambda चलते समय वह variable मौजूद होना चाहिए।Lambda में mutable क्यों इस्तेमाल होता है?
mutable लगाने से lambda अपनी copies बदल सकता है, जैसे value से capture किया counter। बाहर के मूल variable पर इसका असर नहीं होता।