لماذا لامدا؟
قبل C++11، استخدام دالة كمعامل (مثل معيار ترتيب مخصّص) يحتاج تعريف دالة منفصلة باسم، حتى لو استُخدمت مرة واحدة فقط:
bool descending(int a, int b) { return a > b; } // دالة منفصلة لاستخدام واحد
sort(v.begin(), v.end(), descending);
لامدا تكتب نفس الدالة inline بمكان استخدامها مباشرة:
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
الصياغة
[capture](params) -> ReturnType { body }
[]قائمة الالتقاط: أي متغيّرات من النطاق المحيط تصل للامدا.()معاملات عادية، تمامًا كأي دالة.-> ReturnTypeنوع الإرجاع — اختياري غالبًا، المترجم يستنتجه تلقائيًا.
auto square = [](int x) { return x * x; };
cout << square(5); // 25
auto greet = []() { cout << "مرحبًا!"; };
greet();
قائمة الالتقاط بالتفصيل
int threshold = 10;
auto byValue = [threshold](int x) { return x > threshold; };
// نسخة من threshold وقت إنشاء اللامدا — تعديل threshold لاحقًا لا يؤثّر
auto byRef = [&threshold](int x) { return x > threshold; };
// مرجع مباشر لـ threshold — أي تعديل لاحق ينعكس
auto all = [=](int x) { return x > threshold; }; // كل شيء بالنسخ
auto allRef = [&](int x) { return x > threshold; }; // كل شيء بالمرجع
| الصيغة | المعنى |
|---|---|
[] | لا التقاط — لامدا مستقلّة تمامًا |
[x] | التقاط x بالنسخ فقط |
[&x] | التقاط x بالمرجع فقط |
[=] | كل المتغيّرات المستخدَمة، بالنسخ |
[&] | كل المتغيّرات المستخدَمة، بالمرجع |
لامدا مع خوارزميات STL
هذا هو الاستخدام الأشيع فعليًا — لامدا تجعل خوارزميات <algorithm> قابلة
للتخصيص بسرعة:
vector<int> nums = {5, 2, 8, 1, 9};
// ترتيب تنازلي
sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; });
// عدّ العناصر الأكبر من قيمة معيّنة
int threshold = 3;
int count = count_if(nums.begin(), nums.end(),
[threshold](int n) { return n > threshold; });
// تطبيق عملية على كل عنصر
for_each(nums.begin(), nums.end(), [](int n) { cout << n << " "; });
لامدا كمتغيّر يُخزَّن ويُستدعى لاحقًا
#include <functional>
std::function<int(int, int)> add = [](int a, int b) { return a + b; };
cout << add(3, 4); // 7
// لامدا يمكن إرجاعها من دالة أخرى
auto makeMultiplier(int factor) {
return [factor](int x) { return x * factor; };
}
auto triple = makeMultiplier(3);
cout << triple(5); // 15
أخطاء شائعة
- التقاط
[&]لمتغيّر محلي ثم تخزين اللامدا لاستدعائها بعد خروج ذلك المتغيّر من نطاقه — مرجع معلَّق وسلوك غير معرَّف. - استخدام
[=]لالتقاط كائنات كبيرة دون داعٍ — يُنسخ الكائن كاملًا مع كل استدعاء. - نسيان أن
[x]تلتقط قيمةxوقت إنشاء اللامدا، لا وقت استدعائها.
🎯 التالي: خوارزميات STL — sort وfind وtransform بعمق أكبر مع لامدا.