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

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. enum class แบบมีขอบเขต
  2. ยูเนียนและความเสี่ยง
  3. std::variant
  4. std::visit
← กลับไปที่ C++ Academy