std::variant
ยูเนียนที่ปลอดภัยด้านชนิด
std::variant เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
ยูเนียนที่ปลอดภัยด้านชนิดข้อมูล
std::variant เก็บค่าได้เพียงหนึ่งค่าจากรายการชนิดข้อมูลที่กำหนดไว้ และ จดจำว่าค่านั้นเป็นชนิดใด ให้รวม <variant> เพื่อใช้งาน
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 10;
std::cout << std::get<int>(v) << "\n";
}การกำหนดชนิดข้อมูลที่แตกต่างกัน
คุณสามารถกำหนดค่าใหม่ให้วาเรียนต์เป็นชนิดทางเลือกใดก็ได้ วาเรียนต์จะอัปเดตชนิดทางเลือกที่กำลังใช้งานอยู่โดยอัตโนมัติ
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 5;
v = 3.14; // now holds a double
std::cout << std::get<double>(v) << "\n";
}การตรวจสอบชนิดที่กำลังใช้งานอยู่
std::holds_alternative<T>(v) บอกว่าวาเรียนต์กำลังเก็บชนิด T อยู่หรือไม่
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 2.0;
std::cout << std::holds_alternative<double>(v) << "\n";
std::cout << std::holds_alternative<int>(v) << "\n";
}ฟังก์ชัน index()
v.index() ส่งคืนตำแหน่งแบบเริ่มนับจากศูนย์ของชนิดที่กำลังใช้งานอยู่ในรายการชนิดข้อมูล
#include <iostream>
#include <variant>
int main() {
std::variant<int, double, char> v = (char)65;
std::cout << v.index() << "\n"; // 2
}การเข้าถึงอย่างปลอดภัยด้วย std::get
std::get<T> ส่งคืนค่าหาก T กำลังใช้งานอยู่ มิฉะนั้นจะ โยนข้อยกเว้น std::bad_variant_access จึงไม่มีค่าขยะที่เกิดขึ้นโดยไม่แจ้งให้ทราบ
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 7;
try {
std::cout << std::get<double>(v) << "\n";
} catch (const std::bad_variant_access& e) {
std::cout << "wrong type!\n";
}
}get_if ที่ไม่โยนข้อยกเว้น
std::get_if<T>(&v) ส่งคืนตัวชี้ไปยังค่า หรือส่งคืน nullptr หาก T ไม่ได้กำลังใช้งานอยู่ เหมาะอย่างยิ่งสำหรับการตรวจสอบโดยไม่ต้องแยกแขนง
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 9;
if (auto p = std::get_if<int>(&v))
std::cout << "int " << *p << "\n";
}การสร้างค่าเริ่มต้น
วาเรียนต์ที่สร้างขึ้นด้วยค่าเริ่มต้นจะเก็บค่าที่สร้างด้วยการกำหนดค่าเริ่มต้นของชนิดข้อมูล แรก จัดลำดับชนิดข้อมูลให้ชนิดแรกเป็นค่าเริ่มต้นที่เหมาะสม
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v; // holds int 0
std::cout << std::get<int>(v) << "\n";
}การเก็บสตริง
แตกต่างจากยูเนียนดิบ วาเรียนต์สามารถเก็บชนิดที่ไม่ใช่ชนิดพื้นฐาน เช่น std::string ได้อย่างปลอดภัย โดยระบบจะจัดการอายุการใช้งานให้คุณ
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = std::string("hello");
std::cout << std::get<std::string>(v) << "\n";
}วาเรียนต์ในฐานะชนิดค่าที่ส่งคืน
ฟังก์ชันสามารถส่งคืนหนึ่งชนิดจากหลายชนิดได้ด้วยการส่งคืนวาเรียนต์ จากนั้นผู้เรียกจะตรวจสอบวาเรียนต์เพื่อดูว่าชนิดใดถูกส่งกลับมา
#include <iostream>
#include <string>
#include <variant>
std::variant<int, std::string> parse(bool ok) {
if (ok) return 42;
return std::string("error");
}
int main() {
auto r = parse(false);
if (auto s = std::get_if<std::string>(&r)) std::cout << *s << "\n";
}emplace สำหรับการเปลี่ยนค่าโดยตรงภายใน
v.emplace<T>(args...) สร้างค่าใหม่ชนิด T โดยตรงภายในวาเรียนต์ และเปลี่ยนชนิดทางเลือกที่กำลังใช้งานอยู่
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = 1;
v.emplace<std::string>("switched");
std::cout << std::get<std::string>(v) << "\n";
}เหตุใดจึงควรเลือกใช้วาเรียนต์
std::variant ให้ประสิทธิภาพด้านหน่วยความจำแบบยูเนียนพร้อมความปลอดภัยด้านชนิดข้อมูลอย่างเต็มรูปแบบ โดยติดตามชนิดที่กำลังใช้งานอยู่ จัดการอายุการใช้งาน และปฏิเสธการเข้าถึงด้วยชนิดที่ไม่ถูกต้อง บทเรียนถัดไปจะแสดงวิธีประมวลผลวาเรียนต์ที่กระชับที่สุด
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ตรวจสอบความเข้าใจของคุณเกี่ยวกับ std::variant
ทบทวน
คุณได้เรียนรู้เกี่ยวกับ std::variant:
- เก็บค่าหนึ่งค่าจากหลายชนิด และติดตามว่าค่านั้นเป็นชนิดใด
holds_alternative/index()ใช้ตรวจสอบชนิดที่กำลังใช้งานอยู่std::getจะโยนข้อยกเว้นเมื่อชนิดไม่ตรงกัน ส่วนget_ifจะส่งคืนตัวชี้หรือค่าว่าง- เก็บชนิดที่ไม่ใช่ชนิดพื้นฐาน เช่น
std::stringได้อย่างปลอดภัย
คำถามที่พบบ่อย
บทเรียน “std::variant” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “std::variant” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “std::variant”
ยูเนียนที่ปลอดภัยด้านชนิด คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “std::variant” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ