Z
ZHANK
编程在线教程C++ 教程std::optional 与 std::variant
STL 容器深入

std::optional 与 std::variant

optional 表达可能无值、variant 类型安全联合体、std::any

std::optional 与 std::variant

C++17 引入了 optional(可能无值)和 variant(类型安全联合体)——告别 NULL 和裸 union。

学完本章你将: 掌握 optional 表达可空、variant 多类型、any 任意类型。


optional —— 值可能存在

cpp
#include <optional>
#include <iostream>

std::optional<int> divide(int a, int b) {
    if (b == 0) return std::nullopt;  // 无值
    return a / b;
}

int main() {
    auto result = divide(10, 2);

    // 方式 1:has_value
    if (result.has_value())
        std::cout << result.value() << "\n";  // 5

    // 方式 2:value_or(推荐)
    std::cout << result.value_or(-1) << "\n";

    // 方式 3:解引用
    std::cout << *result << "\n";
}

variant —— 类型安全联合体

cpp
#include <variant>

using Value = std::variant<int, double, std::string>;

void print(Value v) {
    std::visit([](auto&& arg) {
        std::cout << arg << "\n";
    }, v);

    // 或按类型处理
    if (std::holds_alternative<int>(v))
        std::cout << "int: " << std::get<int>(v) << "\n";
}

int main() {
    Value v1 = 42;
    Value v2 = 3.14;
    Value v3 = std::string("Hello");

    print(v1);  // 42
    print(v2);  // 3.14
    print(v3);  // Hello
}

any —— 任意类型(慎用)

cpp
#include <any>

std::any a = 42;
a = std::string("Hello");
a = 3.14;

// 取出必须知道类型
std::cout << std::any_cast<double>(a) << "\n";
// std::any_cast<int>(a);  // ❌ 抛 std::bad_any_cast