การสร้างเจเนอเรเตอร์อย่างง่าย
สร้างคอร์ูทีนเจเนอเรเตอร์ที่ส่งคืนค่าแบบประเมินเมื่อจำเป็น
การสร้างเจเนอเรเตอร์อย่างง่าย เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- แนวคิดคอร์ูทีน co_await co_yield co_return
- การสร้างเจเนอเรเตอร์อย่างง่าย
- งานอะซิงโครนัสและชนิด Awaiter
- การจัดสรรเฟรมคอร์ูทีน