Skip to content

Utils_SimpleVariant

SweerItTer edited this page Feb 21, 2026 · 4 revisions

SimpleVariant API 文档

概述

SimpleVariant 是 utilsCore Utils 模块的核心类,提供简单的变体类型功能,支持在编译时指定多种类型的存储和访问。

职责

  • 存储多种类型的值(编译时指定)
  • 类型安全的访问
  • 运行时类型索引查询
  • 递归存储结构

适用场景

  • 配置管理
  • 消息传递
  • 插件系统
  • 需要存储多种类型的场景

依赖关系

  • 依赖: 标准库
  • 被依赖: 配置系统、消息系统等模块

类分析

SimpleVariant 类

职责与用途

SimpleVariant 是变体类型的封装模板类,提供:

  • 多类型存储(编译时指定)
  • 类型安全访问
  • 类型索引查询
  • 递归存储结构

设计模式

  • 变体模式: 存储多种类型
  • 递归模板: 使用递归结构存储多种类型
  • 类型擦除: 隐藏具体类型

模板参数

template <typename... Types>
class SimpleVariant

说明:

  • Types...: 可变参数模板,指定可以存储的类型列表
  • 不允许重复类型(编译时检查)

公共 API 方法

构造函数

SimpleVariant() = default;
template <typename T>
SimpleVariant(T val);

参数说明:

  • val (输入): 初始值

返回值: 无

所有权归属:

  • SimpleVariant 拥有值的所有权

注意事项:

  1. 默认构造创建未初始化的变体(typeIndex_ = -1)
  2. 模板构造函数自动设置值
  3. 必须在 Types... 类型列表中

使用例程:

// 定义支持 int, double, std::string 的变体
SimpleVariant<int, double, std::string> v1;

// 模板构造
SimpleVariant<int, double, std::string> v2(42);
SimpleVariant<int, double, std::string> v3(3.14);
SimpleVariant<int, double, std::string> v4(std::string("hello"));

set() - 设置值

template <typename T>
void set(T val);

参数说明:

  • val (输入): 新值

返回值: 无

所有权归属:

  • 值所有权转移给变体

注意事项:

  1. T 必须在 Types... 类型列表中
  2. 类型不匹配时抛出异常
  3. 自动设置 typeIndex_

使用例程:

SimpleVariant<int, double, std::string> v;

v.set(42);                       // 设置 int
v.set(3.14);                     // 设置 double
v.set(std::string("hello"));     // 设置 string

get() - 获取值

template <typename T>
T get() const;

参数说明: 无

返回值: 存储的值

所有权归属:

  • 返回值由调用者持有

注意事项:

  1. T 必须在 Types... 类型列表中
  2. 类型不匹配时抛出异常
  3. 返回值的副本

使用例程:

SimpleVariant<int, double, std::string> v;
v.set(42);

int value = v.get<int>();  // 返回 42

index() - 获取类型索引

int index() const;

参数说明: 无

返回值:

  • 成功: 类型索引(从 0 开始)
  • 失败: -1(未初始化)

所有权归属:

  • 只读访问

注意事项:

  1. 返回当前存储类型的索引
  2. 索引对应 Types... 中的顺序
  3. 未初始化时返回 -1

使用例程:

SimpleVariant<int, double, std::string> v;

v.set(42);
printf("Index: %d\n", v.index());  // 0 (int)

v.set(3.14);
printf("Index: %d\n", v.index());  // 1 (double)

v.set(std::string("hello"));
printf("Index: %d\n", v.index());  // 2 (string)

内部实现

VariantStorage 递归存储结构

template <typename TFirst, typename... TRest>
struct VariantStorage {
    TFirst first;
    VariantStorage<TRest...> rest;
};

// 递归终止
template <typename TLast>
struct VariantStorage<TLast> {
    TLast first;
};

说明:

  • 使用递归结构存储多种类型
  • 每个层级存储一个类型
  • 递归终止时存储最后一个类型

assign 递归赋值

template <typename T, typename TFirst, typename... TRest>
int assign(T val, VariantStorage<TFirst, TRest...>* s, int currentIndex = 0) {
    if (std::is_same<T, TFirst>::value) {
        s->first = val;
        return currentIndex;
    } else {
        return assign<T, TRest...>(val, &s->rest, currentIndex + 1);
    }
}

参数说明:

  • val (输入): 要赋值的值
  • s (输入): VariantStorage 指针
  • currentIndex (输入): 当前类型索引(默认0)

返回值: 类型在类型列表中的索引

注意事项:

  1. 递归遍历类型列表
  2. 找到匹配类型时赋值并返回索引
  3. 继续递归直到找到匹配类型

assign 终止条件(最后一个类型)

template <typename T, typename TLast>
int assign(T val, VariantStorage<TLast>* s, int currentIndex = 0) {
    if (std::is_same<T, TLast>::value) {
        s->first = val;
        return currentIndex;
    } else {
        throw std::runtime_error("Type not in variant");
    }
}

参数说明:

  • val (输入): 要赋值的值
  • s (输入): VariantStorage 指针(最后一个类型)
  • currentIndex (输入): 当前类型索引

返回值: 类型在类型列表中的索引

注意事项:

  1. 终止条件:处理最后一个类型
  2. 如果类型不匹配,抛出 std::runtime_error 异常
  3. 这是递归的终止点

getImpl 递归获取

template <typename T, typename TFirst, typename... TRest>
T getImpl(const VariantStorage<TFirst, TRest...>* s) const {
    if (std::is_same<T, TFirst>::value) {
        return s->first;
    } else {
        return getImpl<T, TRest...>(&s->rest);
    }
}

参数说明:

  • s (输入): VariantStorage 指针

返回值: 存储的值

注意事项:

  1. 递归遍历类型列表
  2. 找到匹配类型时返回值
  3. 继续递归直到找到匹配类型

getImpl 终止条件(最后一个类型)

template <typename T, typename TLast>
T getImpl(const VariantStorage<TLast>* s) const {
    if (std::is_same<T, TLast>::value) {
        return s->first;
    } else {
        throw std::runtime_error("Type not in variant");
    }
}

参数说明:

  • s (输入): VariantStorage 指针(最后一个类型)

返回值: 存储的值

注意事项:

  1. 终止条件:处理最后一个类型
  2. 如果类型不匹配,抛出 std::runtime_error 异常
  3. 这是递归的终止点

典型使用场景

场景 1: 基本使用

SimpleVariant<int, double, std::string> v;

// 设置值
v.set(42);
printf("Value: %d, Index: %d\n", v.get<int>(), v.index());

v.set(3.14);
printf("Value: %f, Index: %d\n", v.get<double>(), v.index());

v.set(std::string("hello"));
printf("Value: %s, Index: %d\n", v.get<std::string>().c_str(), v.index());

场景 2: 构造函数

// 模板构造
SimpleVariant<int, double, std::string> v1(42);
SimpleVariant<int, double, std::string> v2(3.14);
SimpleVariant<int, double, std::string> v3(std::string("hello"));

场景 3: 配置管理

using ConfigVariant = SimpleVariant<int, double, std::string, bool>;

std::map<std::string, ConfigVariant> config;

config["width"] = 1920;
config["height"] = 1080;
config["name"] = std::string("display");
config["enabled"] = true;

int width = config["width"].get<int>();
std::string name = config["name"].get<std::string>();
bool enabled = config["enabled"].get<bool>();

场景 4: 消息传递

using MessageData = SimpleVariant<int, double, std::string>;

struct Message {
    std::string type;
    MessageData data;
};

Message msg;
msg.type = "update";
msg.data.set(42);

// 处理消息
if (msg.type == "update") {
    int value = msg.data.get<int>();
    printf("Update value: %d\n", value);
}

场景 5: 多种类型

// 自定义类型
struct Point { int x, y; };

SimpleVariant<int, double, std::string, Point> v;

v.set(Point{10, 20});
Point p = v.get<Point>();
printf("Point: (%d, %d)\n", p.x, p.y);

注意事项

  1. 编译时指定: 类型列表在编译时指定,不可运行时修改
  2. 不允许重复: 类型列表中不允许重复类型(编译时检查)
  3. 类型安全: 访问前确保类型匹配
  4. 异常处理: get() 类型不匹配时抛出异常
  5. 索引查询: 使用 index() 查询当前类型索引
  6. 递归结构: 使用递归模板实现,类型列表过长可能影响编译速度
  7. 副本返回: get() 返回值的副本,注意大型对象的性能
  8. 未初始化: 默认构造的变体未初始化(index() = -1)

相关文档


参考资料

主页

API 文档

DMA 模块

DRM 模块

NET 模块

V4L2 模块

V4L2Param 模块

RGA 模块

MPP 模块

Sys 模块

Mouse 模块

Utils 模块

Clone this wiki locally