std::visit
ประมวลผลทางเลือกของ variant
std::visit เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงควรใช้ std::visit
การตรวจสอบชนิดทางเลือกแต่ละชนิดด้วย get_if ด้วยตนเองทำให้โค้ดยืดยาว std::visit จะนำฟังก์ชันที่เรียกใช้ได้ไปใช้กับชนิดที่วาเรียนต์กำลังเก็บอยู่ โดยจัดการการเลือกเรียกให้คุณ
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 4;
std::visit([](auto x){ std::cout << x << "\n"; }, v);
}ตัวเยี่ยมชมด้วยแลมบ์ดาทั่วไป
แลมบ์ดาที่รับ auto สามารถทำงานกับชนิดทางเลือกทุกชนิดได้ หากเนื้อความภายในคอมไพล์ได้กับทุกชนิด ในที่นี้เราจะแสดงชนิดใดก็ตามที่กำลังใช้งานอยู่
#include <iostream>
#include <string>
#include <variant>
int main() {
std::variant<int, std::string> v = std::string("hi");
std::visit([](const auto& x){ std::cout << x << "\n"; }, v);
}การส่งคืนค่า
std::visit สามารถส่งคืนค่าได้ ทุกแขนงต้องส่งคืนชนิดเดียวกัน
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 2.5;
double d = std::visit([](auto x){ return x * 2.0; }, v);
std::cout << d << "\n";
}พฤติกรรมแยกตามชนิดด้วย if constexpr
หากต้องการให้ทำงานแตกต่างกันตามชนิดภายในแลมบ์ดาทั่วไปหนึ่งตัว ให้ใช้ if constexpr ร่วมกับ std::decay_t และ std::is_same_v
#include <iostream>
#include <string>
#include <variant>
#include <type_traits>
int main() {
std::variant<int, std::string> v = 5;
std::visit([](const auto& x){
using T = std::decay_t<decltype(x)>;
if constexpr (std::is_same_v<T, int>) std::cout << "int " << x << "\n";
else std::cout << "str " << x << "\n";
}, v);
}ตัวเยี่ยมชมแบบโครงสร้าง
คุณยังสามารถเขียนโครงสร้างที่มีโอเวอร์โหลดของ operator() หลายรายการ โดยมีหนึ่งรายการต่อชนิดข้อมูล คอมไพเลอร์จะเลือกโอเวอร์โหลดที่ตรงกัน
#include <iostream>
#include <string>
#include <variant>
struct Printer {
void operator()(int i) const { std::cout << "int " << i << "\n"; }
void operator()(const std::string& s) const { std::cout << "str " << s << "\n"; }
};
int main() {
std::variant<int, std::string> v = std::string("yo");
std::visit(Printer{}, v);
}สำนวน overloaded
ตัวช่วยที่ได้รับความนิยมนี้รวมแลมบ์ดาหลายตัวให้เป็นตัวเยี่ยมชมหนึ่งตัว แลมบ์ดาแต่ละตัวจะจัดการชนิดข้อมูลเฉพาะ
#include <iostream>
#include <string>
#include <variant>
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
int main() {
std::variant<int, std::string> v = 8;
std::visit(overloaded{
[](int i){ std::cout << "i=" << i << "\n"; },
[](const std::string& s){ std::cout << "s=" << s << "\n"; }
}, v);
}ความครอบคลุมทุกกรณี
ตัวเยี่ยมชมต้องจัดการกับชนิดทางเลือก ทุกชนิด มิฉะนั้นโค้ดจะคอมไพล์ไม่ผ่าน การตรวจสอบขณะคอมไพล์นี้ช่วยป้องกันการลืมกรณีใดกรณีหนึ่ง
การเยี่ยมชมและการเปลี่ยนค่า
หากส่งวาเรียนต์ด้วยการอ้างอิงที่ไม่ใช่ const ตัวเยี่ยมชมจะสามารถแก้ไขค่าที่เก็บไว้โดยตรงภายในได้
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> v = 10;
std::visit([](auto& x){ x += 1; }, v);
std::cout << std::get<int>(v) << "\n";
}วาเรียนต์หลายตัว
std::visit รับวาเรียนต์หลายตัวพร้อมกันได้ โดยตัวเยี่ยมชมจะได้รับอาร์กิวเมนต์หนึ่งรายการต่อวาเรียนต์หนึ่งตัว
#include <iostream>
#include <variant>
int main() {
std::variant<int, double> a = 2;
std::variant<int, double> b = 3.0;
auto sum = std::visit([](auto x, auto y){ return x + y; }, a, b);
std::cout << sum << "\n";
}การเลือกรูปแบบตัวเยี่ยมชม
ใช้แลมบ์ดา auto ทั่วไปสำหรับการจัดการที่เหมือนกัน ใช้สำนวน overloaded สำหรับตรรกะที่แยกตามชนิดอย่างเป็นระเบียบ และใช้ตัวเยี่ยมชมแบบโครงสร้างเมื่อจำเป็นต้องนำพฤติกรรมกลับมาใช้ซ้ำในหลายจุดเรียก
การเยี่ยมชมเทียบกับ get_if
get_if เหมาะสำหรับการตรวจสอบอย่างรวดเร็วเพียงครั้งเดียว แต่ std::visit รองรับการขยายได้ดีกว่า โดยบังคับให้ครอบคลุมทุกกรณีและรวมตรรกะของแต่ละชนิดไว้ในที่เดียว
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ตรวจสอบความเข้าใจของคุณเกี่ยวกับ std::visit
ทบทวน
คุณได้เรียนรู้เกี่ยวกับ std::visit:
- กระจายการเรียกสิ่งที่เรียกใช้ได้ไปยังชนิดทางเลือกที่กำลังใช้งานอยู่
- ใช้แลมบ์ดาทั่วไป
if constexprตัวเยี่ยมชมแบบโครงสร้าง หรือสำนวน overloaded - ตัวเยี่ยมชมต้องครอบคลุมทุกกรณี (ตรวจสอบขณะคอมไพล์)
- สามารถส่งคืนค่าและเยี่ยมชมวาเรียนต์หลายตัวพร้อมกันได้
เรียนรู้ C++ ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “std::visit” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “std::visit” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “std::visit”
ประมวลผลทางเลือกของ variant คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “std::visit” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม
ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ