مقدمة في تعبيرات Lambda
جزء من قسم Logic & Flow في رحلة C++ على Coddy — الدرس 42 من 56.
تعبيرات لامدا (Lambda expressions) هي ميزة قوية في لغة C++ تتيح لك إنشاء دوال صغيرة ومجهولة الهوية (anonymous functions) في المكان الذي تحتاج إليها فيه تماماً. فكر فيها كدوال مصغرة يمكنك تعريفها واستخدامها دون الحاجة إلى كتابة إعلان دالة (function declaration) منفصل.
يتبع بناء الجملة الأساسي لتعبير لامبدا (lambda expression) هذا النمط: [](){}. تُسمى الأقواس المربعة [] بـ جملة الالتقاط (capture clause)، وتحتوي الأقواس () على المعاملات (تماماً مثل الدوال العادية)، وتحتوي الأقواس المتعرجة {} على جسم الدالة.
تتحكم جملة الالتقاط في المتغيرات التي يمكن للامبدا استخدامها من النطاق المحيط. الأشكال الأكثر شيوعاً هي:
[=] — التقاط جميع المتغيرات المحلية بالقيمة (by value) (تحصل اللامبدا على نسختها الخاصة)[&] — التقاط جميع المتغيرات المحلية بالمرجع (by reference) (تصل اللامبدا إلى المتغيرات الأصلية)[] — لا تلتقط شيئاً (لا يمكن للامبدا استخدام أي متغيرات خارجية)إليك كيفية إنشاء واستدعاء lambda بسيطة:
auto myLambda = []() {
std::cout << "Hello from Lambda!" << std::endl;
};
myLambda(); // استدعاء دالة lambdaيمكنك أيضاً تعريف وتنفيذ lambda بشكل فوري دون تخزينها في متغير:
[]() {
std::cout << "Immediate execution!" << std::endl;
}();تعبيرات لامبدا (Lambda expressions) مفيدة بشكل خاص للدوال القصيرة التي تُستخدم لمرة واحدة والتي لا ترغب في تعريفها بشكل منفصل. فهي تجعل كودك أكثر إيجازاً وتبقي المنطق البرمجي المرتبط ببعضه البعض قريباً.
التحدي
سهلقم بإنشاء برنامج يوضح الصيغة الأساسية وتنفيذ تعبيرات لامبدا (lambda expressions). سيختبر هذا التحدي فهمك لكيفية تعريف واستدعاء دوال لامبدا البسيطة بدون معاملات.
يجب أن يقوم برنامجك بما يلي:
- إنشاء تعبير لامبدا يطبع
Hello from Lambda! - تخزين تعبير لامبدا هذا في متغير باستخدام الكلمة المفتاحية
auto - استدعاء دالة لامبدا لتنفيذها
- إنشاء تعبير لامبدا ثانٍ يطبع
Lambda executed successfully! - تنفيذ تعبير لامبدا الثاني هذا فوراً دون تخزينه في متغير
استخدم تنسيق المخرجات الدقيق التالي:
Hello from Lambda!
Lambda executed successfully!تذكر أن تعبيرات لامبدا تستخدم الصيغة [](){} حيث تمثل الأقواس المربعة [] جملة الالتقاط (capture clause)، والأقواس الدائرية () تحمل المعاملات (فارغة في هذا التحدي)، والأقواس المتعرجة {} تحتوي على جسم الدالة. يمكنك تخزين لامبدا في متغير باستخدام auto variableName = [](){...}; ثم استدعاؤه باستخدام variableName();. وللتنفيذ الفوري، يمكنك استخدام الصيغة [](){...}(); التي تقوم بتعريف واستدعاء لامبدا في جملة واحدة.
ورقة مرجعية
تعبيرات Lambda هي دوال مجهولة (anonymous functions) يمكن تعريفها بشكل مضمن (inline). وهي تستخدم الصيغة [](){} حيث:
[]- عبارة الالتقاط (تتحكم في الوصول إلى المتغيرات الخارجية)()- المعاملات{}- جسم الدالة
أشكال عبارة الالتقاط الشائعة:
[]- لا تلتقط شيئاً[=]- التقاط جميع المتغيرات الخارجية بالقيمة[&]- التقاط جميع المتغيرات الخارجية بالمرجع
تخزين واستدعاء lambda:
auto myLambda = []() {
std::cout << "Hello from Lambda!" << std::endl;
};
myLambda(); // استدعاء دالة lambdaتنفيذ lambda على الفور:
[]() {
std::cout << "Immediate execution!" << std::endl;
}();جرّب بنفسك
#include <iostream>
using namespace std;
int main() {
// TODO: اكتب كودك أدناه
// أنشئ تعبير لامدا (lambda expression) يطبع "Hello from Lambda!"
// قم بتخزينه في متغير باستخدام الكلمة المفتاحية auto
// استدعِ دالة لامدا
// أنشئ لامدا ثانية تطبع "Lambda executed successfully!"
// قم بتنفيذها فوراً دون تخزينها في متغير
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Logic & Flow
1المؤشرات والذاكرة
ما هو المؤشر؟معامل العنوان (Address-Of)معامل الوصول للقيمة (Dereference)المؤشرات الفارغة (Null Pointers)المؤشرات والمصفوفاتالذاكرة الديناميكية باستخدام 'new'تحرير الذاكرة باستخدام 'delete'مراجعة - تمارين على المؤشرات4الخرائط (أزواج مفتاح-قيمة)
مقدمة إلى std::mapإنشاء خريطةالوصول إلى القيم وتعديلهاالتحقق من وجود المفاتيححذف الأزواجالتكرار عبر الخريطةمراجعة - تكرار الكلمات7الدوال المتقدمة
التمرير بالمرجعمقدمة في تعبيرات Lambdaتعبيرات Lambda مع المعاملاتتعبيرات Lambda مع قيم الإرجاعمقدمة في الاستدعاء الذاتيالمضروب بالاستدعاء الذاتيالفرز باستخدام Lambda2المتجهات (المصفوفات الديناميكية)
مقدمة إلى std::vectorإنشاء Vectorإضافة العناصرالوصول إلى العناصرحجم الـ Vectorالتكرار باستخدام For Loopالـ Range-Based For Loopإزالة العناصرملخص - عمليات الـ Vector