std::bind
اربط المعاملات بالكائنات القابلة للاستدعاء
std::bind درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
ما هو std::bind؟
ينشئ std::bind كيانًا جديدًا قابلًا للاستدعاء من خلال تثبيت بعض الوسائط لكيان موجود. ويُسمى ذلك التطبيق الجزئي.
- يوجد في
<functional>. - يعيد كائنًا قابلًا للاستدعاء غير محدد النوع.
#include <iostream>
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
auto add10 = std::bind(add, 10, 5);
std::cout << add10() << '\n';
return 0;
}العناصر النائبة
تحدد العناصر النائبة مثل std::placeholders::_1 الوسائط التي سيتم توفيرها لاحقًا عند استدعاء الكائن المربوط.
#include <iostream>
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
using namespace std::placeholders;
auto add10 = std::bind(add, 10, _1);
std::cout << add10(7) << '\n';
return 0;
}إعادة ترتيب الوسائط
يمكن أن تظهر العناصر النائبة بأي ترتيب، مما يتيح تبديل مواضع الوسائط التي يوفرها المستدعي.
#include <iostream>
#include <functional>
int sub(int a, int b) { return a - b; }
int main() {
using namespace std::placeholders;
auto flipped = std::bind(sub, _2, _1);
std::cout << flipped(3, 10) << '\n';
return 0;
}تثبيت عدة وسائط
يمكنك تثبيت عدة وسائط في آن واحد، مع ترك الوسائط الأخرى كعناصر نائبة.
#include <iostream>
#include <functional>
int volume(int l, int w, int h) { return l * w * h; }
int main() {
using namespace std::placeholders;
auto box = std::bind(volume, 2, _1, 5);
std::cout << box(3) << '\n';
return 0;
}تخزين النتيجة
يمكن تخزين الكائن الذي يعيده std::bind في std::function للحصول على نوع ملموس ذي اسم.
#include <iostream>
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
using namespace std::placeholders;
std::function<int(int)> add100 = std::bind(add, 100, _1);
std::cout << add100(1) << '\n';
return 0;
}تثبيت دوال الأعضاء
يمكن أن يستهدف std::bind دالة عضو من خلال تمرير مؤشر العضو وكائن أو عنصر نائب لـ this.
#include <iostream>
#include <functional>
struct Counter {
int add(int x) { return value += x; }
int value = 0;
};
int main() {
using namespace std::placeholders;
Counter c;
auto bump = std::bind(&Counter::add, &c, _1);
std::cout << bump(5) << ' ' << bump(3) << '\n';
return 0;
}التثبيت بالقيمة مقابل المرجع
تُنسخ الوسائط المثبتة افتراضيًا. غلّف أحدها في std::ref لتثبيته بالمرجع، بحيث تصبح التغييرات مرئية.
#include <iostream>
#include <functional>
void addTo(int& target, int amount) { target += amount; }
int main() {
using namespace std::placeholders;
int total = 0;
auto acc = std::bind(addTo, std::ref(total), _1);
acc(5);
acc(10);
std::cout << total << '\n';
return 0;
}استخدام الكيانات المربوطة القابلة للاستدعاء في الخوارزميات
يعمل الكيان المربوط القابل للاستدعاء كدالة شرطية أو عملية في الخوارزميات القياسية.
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
bool greaterThan(int x, int limit) { return x > limit; }
int main() {
using namespace std::placeholders;
std::vector<int> v = {1, 5, 8, 2, 9};
auto over4 = std::bind(greaterThan, _1, 4);
std::cout << std::count_if(v.begin(), v.end(), over4) << '\n';
return 0;
}تداخل bind
يمكن تركيب تعبيرات bind، لكن ذلك يصبح سريعًا صعب القراءة. ويظل كل عنصر نائب يشير إلى وسائط المستدعي النهائي.
#include <iostream>
#include <functional>
int add(int a, int b) { return a + b; }
int times(int a, int b) { return a * b; }
int main() {
using namespace std::placeholders;
auto f = std::bind(add, std::bind(times, 2, _1), 3);
std::cout << f(5) << '\n';
return 0;
}تجاهل الوسائط الإضافية
إذا كان الاستدعاء المربوط يستخدم بعض العناصر النائبة فقط، فسيتم ببساطة تجاهل أي وسائط إضافية تُمرَّر وقت الاستدعاء.
#include <iostream>
#include <functional>
int show(int a) { return a; }
int main() {
using namespace std::placeholders;
auto f = std::bind(show, _1);
std::cout << f(42, 99, 100) << '\n';
return 0;
}متى تكون لامبدا أوضح
يفضّل C++ الحديث غالبًا استخدام لامبدا بدلًا من std::bind لأنها أسهل قراءة، ولأن المترجم يحسن تحسينها.
#include <iostream>
#include <functional>
int add(int a, int b) { return a + b; }
int main() {
auto add10 = [](int x) { return add(10, x); };
std::cout << add10(5) << '\n';
return 0;
}اختبار سريع
اختبر مدى فهمك للعناصر النائبة.
مراجعة
لقد تعلمت كيفية عمل std::bind:
- يثبّت بعض الوسائط ويستخدم العناصر النائبة
_1و_2للوسائط المتبقية - يمكنه إعادة ترتيب الوسائط وتثبيت دوال الأعضاء واستخدام
std::ref - يمكن تخزين النتائج في
std::functionواستخدامها في الخوارزميات - تكون لامبدا غالبًا أوضح في C++ الحديث
بعد ذلك ستقارن بين لامبدا وbind ومؤشرات الدوال لاختيار الأداة المناسبة.
الأسئلة الشائعة
هل درس «std::bind» مجاني؟
نعم — نص درس «std::bind» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «std::bind»؟
اربط المعاملات بالكائنات القابلة للاستدعاء تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «std::bind»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.