تنفيذ مولّد بسيط
ابنِ Coroutine مولّدًا يُنتج القيم بطريقة كسولة.
تنفيذ مولّد بسيط درس مجاني في C++ Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C++ Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C++ Academy 4 دروس في المجموع.
المولّدات بوصفها Coroutines
المولّد هو coroutine يعيد القيم واحدةً تلو الأخرى. وينتج كل استدعاء للمولّد القيمة التالية ثم يعلّق التنفيذ.
نوع المولّد
عرّف فئة تتضمن نوعًا متداخلًا باسم promise_type. ويستخدمه المصرّف لإدارة حالة coroutine.
template <typename T>
struct Generator {
struct promise_type {
T current_value;
Generator get_return_object() {
return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
std::suspend_always yield_value(T value) {
current_value = value;
return {};
}
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> h;
// ... constructors, destructor, next() ...
};استخدام المولّد
بعد تعريفها، تبدو المولّدات شبيهةً بـ yield في Python.
Generator<int> counting() {
int n = 0;
while (true) co_yield n++;
}
auto g = counting();
for (int i = 0; i < 5; ++i) {
std::cout << g.next() << " ";
}
// 0 1 2 3 4coroutine_handle
يعيد المصرّف std::coroutine_handle. وهو يمثل coroutine المعلّقة؛ إذ يمكنك استدعاء resume() أو destroy() أو التحقق باستخدام done().
نقاط التعليق
يؤدي كل co_yield إلى تعليق التنفيذ. وعندما يستدعي المستدعي resume()، يتابع التنفيذ حتى نقطة التعليق التالية أو حتى نهاية coroutine.
initial_suspend وfinal_suspend
نقطتا تخصيص:
initial_suspend— أعدsuspend_alwaysلبدء كسول، أوsuspend_neverلبدء فوريfinal_suspend— تتحكم في التنظيف. وعادةً ما تكونsuspend_alwaysلضمان التدمير الصحيح
C++23 std::generator
أضاف C++23 النوع std::generator في <generator>. ولم تعد بحاجة إلى كتابة النوع يدويًا في الحالات الشائعة.
#include <generator>
std::generator<int> counting() {
int n = 0;
while (true) co_yield n++;
}حلقة for المعتمدة على النطاق
إذا كان نوع المولّد يدعم begin/end، فستعمل حلقة for المعتمدة على النطاق مباشرةً.
for (int x : counting()) {
if (x >= 10) break;
std::cout << x;
}دلالتا السحب والدفع
المولّدات تعتمد على السحب؛ إذ يقود المستدعي عملية التكرار. أما coroutines المعتمدة على الدفع فهي مهام غير متزامنة.
حالات الاستخدام
تُعد المولّدات مناسبةً لـ:
- التسلسلات الكسولة، مثل فيبوناتشي والأعداد الأولية وقارئات الملفات سطرًا سطرًا
- تدفق البيانات من دون إنشاء تمثيل كامل لها في الذاكرة
- التكرار في هياكل شبيهة بالأشجار
اعتبارات الذاكرة
يخصص إطار coroutine في الكومة افتراضيًا. وقد يتمكن المصرّف من حذف هذا التخصيص عندما يسمح الإدراج داخل الدوال بذلك، لذا قِس الأداء عند أهميته.
مكتبات لاستكشافها
للتعلم، توفر cppcoro من تأليف Lewis Baker أنواعًا موثقة جيدًا للمولّدات والمهام. كما يوفر Boost.Asio عمليات إدخال وإخراج ملائمة لـ coroutines. وتضيف إصدارات C++23 وما بعدها دعمًا من المكتبة القياسية.
اختبار سريع
ما نوع المكتبة القياسية في C++23 الخاص بـ coroutines من نوع مولّد؟
مراجعة
تعيد coroutine من نوع مولّد القيم بطريقة كسولة باستخدام co_yield. نفّذها باستخدام فئة تحتوي على promise_type. وقد وحّد C++23 النوع std::generator. وتتميز المولّدات في التسلسلات الكسولة وتدفق البيانات.
الأسئلة الشائعة
هل درس «تنفيذ مولّد بسيط» مجاني؟
نعم — نص درس «تنفيذ مولّد بسيط» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C++ Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C++ Academy 4 دروس في المجموع.
ماذا ستتعلم في «تنفيذ مولّد بسيط»؟
ابنِ Coroutine مولّدًا يُنتج القيم بطريقة كسولة. تتمرن على C++ Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C++ Academy؟
لا تُشترط خبرة سابقة. C++ Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «تنفيذ مولّد بسيط»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C++ Academy هذا؟
نعم. كل درس في C++ Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مفاهيم Coroutines: co_await وco_yield وco_return
- تنفيذ مولّد بسيط
- المهام غير المتزامنة وأنواع Awaiter
- تخصيص إطار Coroutine