0Pricing
C++ Academy · บทเรียน

การสร้างเจเนอเรเตอร์อย่างง่าย

สร้างคอร์ูทีนเจเนอเรเตอร์ที่ส่งคืนค่าแบบประเมินเมื่อจำเป็น

การสร้างเจเนอเรเตอร์อย่างง่าย เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

ตัวสร้างในรูปแบบคอร์รูทีน

ตัวสร้างคือคอร์รูทีนที่ส่งค่าออกมาทีละค่า การเรียกตัวสร้างแต่ละครั้งจะสร้างค่าถัดไปและหยุดชั่วคราว

ชนิด Generator

กำหนดคลาสที่มี promise_type ซ้อนอยู่ภายใน คอมไพเลอร์ใช้ชนิดนี้เพื่อจัดการสถานะของคอร์รูทีน

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() ...
};

การใช้ตัวสร้าง

เมื่อกำหนดตัวสร้างแล้ว การใช้งานจะให้ความรู้สึกคล้ายคำสั่งส่งค่าของ 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 4

ตัวจัดการคอร์รูทีน

คอมไพเลอร์จะส่งคืน std::coroutine_handle ซึ่งแทนคอร์รูทีนที่หยุดชั่วคราวอยู่ คุณสามารถเรียก resume(), destroy() หรือตรวจสอบ done() ได้

จุดหยุดชั่วคราว

ทุก co_yield จะทำให้คอร์รูทีนหยุดชั่วคราว เมื่อผู้เรียกเรียก resume() การทำงานจะดำเนินต่อจนถึงจุดหยุดชั่วคราวถัดไปหรือจบคอร์รูทีน

initial_suspend และ final_suspend

จุดปรับแต่งสองจุด:

  • initial_suspend — ส่งคืน suspend_always เพื่อเริ่มทำงานเมื่อมีการเรียกใช้ หรือ suspend_never เพื่อเริ่มทำงานทันที
  • final_suspend — ควบคุมการเก็บกวาด โดยทั่วไปใช้ suspend_always เพื่อให้ทำลายได้อย่างถูกต้อง

std::generator ของ C++23

C++23 เพิ่ม std::generator ไว้ใน <generator> แล้ว กรณีทั่วไปจึงไม่จำเป็นต้องเขียนชนิดนี้ขึ้นเองอีก

#include <generator>

std::generator<int> counting() {
    int n = 0;
    while (true) co_yield n++;
}

ลูปตามช่วง

หากชนิดตัวสร้างรองรับ begin/end ลูปตามช่วงก็จะทำงานได้ทันที

for (int x : counting()) {
    if (x >= 10) break;
    std::cout << x;
}

ความหมายแบบดึงเทียบกับแบบผลัก

ตัวสร้างทำงานแบบดึงข้อมูล โดยผู้เรียกเป็นผู้ควบคุมการวนซ้ำ ส่วนคอร์รูทีนแบบผลักข้อมูลคืองานแบบไม่พร้อมกัน

กรณีการใช้งาน

ตัวสร้างเหมาะอย่างยิ่งสำหรับ:

  • ลำดับข้อมูลแบบประเมินเมื่อจำเป็น เช่น ฟีโบนักชี จำนวนเฉพาะ และตัวอ่านไฟล์ทีละบรรทัด
  • การส่งข้อมูลต่อเนื่องโดยไม่ต้องสร้างข้อมูลทั้งหมดไว้ล่วงหน้า
  • การวนซ้ำโครงสร้างคล้ายต้นไม้

ข้อพิจารณาด้านหน่วยความจำ

โดยค่าเริ่มต้น เฟรมคอร์รูทีนจะถูกจัดสรรบนฮีป คอมไพเลอร์อาจตัดการจัดสรรนี้ออกได้เมื่อการแทรกโค้ดอนุญาต โปรดวัดประสิทธิภาพเมื่อประสิทธิภาพมีความสำคัญ

ไลบรารีที่ควรศึกษา

สำหรับการเรียนรู้ cppcoro ของ Lewis Baker มีชนิดตัวสร้างและงานที่จัดทำเอกสารไว้อย่างดี Boost.Asio มีการรับส่งข้อมูลที่รองรับคอร์รูทีน ตั้งแต่ C++23 เป็นต้นไป ไลบรารีมาตรฐานก็รองรับความสามารถนี้

ตรวจสอบอย่างรวดเร็ว

ชนิดในไลบรารีมาตรฐาน C++23 สำหรับคอร์รูทีนตัวสร้างคืออะไร?

สรุปทบทวน

คอร์รูทีนตัวสร้างจะส่งค่าออกมาเมื่อจำเป็นด้วย co_yield โดยพัฒนาด้วยคลาสที่มี promise_type อยู่ภายใน C++23 ทำให้ std::generator เป็นมาตรฐาน ตัวสร้างเหมาะอย่างยิ่งสำหรับลำดับข้อมูลแบบประเมินเมื่อจำเป็นและการส่งข้อมูลต่อเนื่อง

คำถามที่พบบ่อย

บทเรียน “การสร้างเจเนอเรเตอร์อย่างง่าย” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างเจเนอเรเตอร์อย่างง่าย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างเจเนอเรเตอร์อย่างง่าย”

สร้างคอร์ูทีนเจเนอเรเตอร์ที่ส่งคืนค่าแบบประเมินเมื่อจำเป็น คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การสร้างเจเนอเรเตอร์อย่างง่าย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม

ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิดคอร์ูทีน co_await co_yield co_return
  2. การสร้างเจเนอเรเตอร์อย่างง่าย
  3. งานอะซิงโครนัสและชนิด Awaiter
  4. การจัดสรรเฟรมคอร์ูทีน
← กลับไปที่ C++ Academy