You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中实现类似SML的‘one of’数据类型?

在C++中实现类似SML的"one of"可选类型

SML里的datatype element = NONE | Value of Structure;本质是可选类型,用来表示一个值要么存在(为Structure类型实例),要么不存在(对应NONE)。C++里有几种成熟的实现方式,不用局限于仅支持常量的enum:

1. 使用C++17的std::optional(推荐)

这是标准库提供的最贴合需求的方案,专门用来处理"存在/不存在"的可选值场景:

#include <optional>

// 假设你的Structure类型定义如下
struct Structure {
    // 自定义成员,比如:
    int id;
    std::string name;
};

// 函数返回可选的Structure实例
std::optional<Structure> get_element() {
    if (/* 满足值存在的业务条件 */) {
        return Structure{1, "example"};
    } else {
        return std::nullopt; // 对应SML中的NONE
    }
}

// 使用示例
int main() {
    auto elem = get_element();
    if (elem.has_value()) {
        // 访问存在的值:用*elem 或 elem.value()
        Structure& val = *elem;
        // 处理val的逻辑
    } else {
        // 处理无值(NONE)的逻辑
    }
}

2. 使用C++17的std::variant(通用变体类型)

如果需要扩展支持更多类型的"one of"场景,std::variant可以表示多种类型中的一种,这里用它绑定std::monostate(对应NONE)和Structure:

#include <variant>
#include <iostream>

struct Structure {
    int data;
};

// 定义对应SML的element的变体类型
using Element = std::variant<std::monostate, Structure>;

Element get_element() {
    if (/* 条件满足 */) {
        return Structure{42};
    } else {
        return std::monostate{}; // 对应NONE
    }
}

// 通过std::visit处理不同状态
void process_element(const Element& elem) {
    std::visit([](auto&& arg) {
        using T = std::decay_t<decltype(arg)>;
        if constexpr (std::is_same_v<T, std::monostate>) {
            std::cout << "Got NONE\n";
        } else if constexpr (std::is_same_v<T, Structure>) {
            std::cout << "Got Structure with data: " << arg.data << "\n";
        }
    }, elem);
}

3. 手动实现可选类型(兼容C++17之前版本)

如果项目使用老版本C++,可以自己封装一个简单的可选类型:

#include <cassert>

struct Structure {
    // 自定义成员
};

class OptionalStructure {
private:
    bool has_value_ = false;
    Structure value_;
public:
    // 构造无值(NONE)的实例
    OptionalStructure() = default;
    // 构造带值的实例
    OptionalStructure(const Structure& val) : has_value_(true), value_(val) {}
    
    bool has_value() const { return has_value_; }
    const Structure& value() const {
        assert(has_value_ && "Accessing value when none exists");
        return value_;
    }
};

// 函数返回示例
OptionalStructure get_element() {
    if (/* 业务条件 */) {
        return Structure{};
    } else {
        return OptionalStructure{};
    }
}

enum不适用的核心原因是它只能表示离散的常量值,无法携带自定义类型(比如Structure)的实例数据,而上面的几种方案都能完美解决"返回Structure实例或无值"的需求。

内容的提问来源于stack exchange,提问作者Ghassen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:23:18