C++ std::holds_alternative示例

如何在模板函数 中使用 std::holds_alternative

在模板函数中使用 std::holds_alternative 非常简单。你只需要将 std::variant 和要检查的类型作为模板参数传递给函数。以下是一个示例,演示如何在模板函数中使用 std::holds_alternative

#include <iostream>
#include <variant>
#include <vector>
#include <string>

template <typename T, typename... Types>
bool check_variant(const std::variant<Types...>& var) {
    return std::holds_alternative<T>(var);
}

int main() {
    std::variant<int, std::vector<int>, std::string> var;
    var = std::vector<int>{1, 2, 3};

    if (check_variant<std::vector<int>>(var)) {
        std::cout << "var 包含 std::vector<int>" << std::endl;
    } else {
        std::cout << "var 不包含 std::vector<int>" << std::endl;
    }

    var = std::string{"Hello, World!"};

    if (check_variant<std::string>(var)) {
        std::cout << "var 包含 std::string" << std::endl;
    } else {
        std::cout << "var 不包含 std::string" << std::endl;
    }

    return 0;
}

在这个示例中,我们定义了一个模板函数 check_variant,它接受一个 std::variant 对象和一个类型 T 作为模板参数。函数内部使用 std::holds_alternative<T>(var) 检查 var 是否包含类型 T 的值。

在 main 函数中,我们创建了一个 std::variant<int, std::vector<int>, std::string> 对象 var,并分别检查它是否包含 std::vector<int> 和 std::string 类型的值。

   /**
    * @brief 读取寄存器值。可读取单个寄存器,寄存器数组,或按索引读取寄存器数组。
    * 如果要读取整个寄存器数组,value传入对应类型的vector,index值被忽略。
    * @tparam T 读取数值类型
    * @param[in] name 寄存器名称
    * @param[in] index 按索引读取寄存器数组中元素,从0开始。
    *           下列两种情况会报错:1) 索引超出数组长度; 2) 寄存器不是数组但index大于0
    * @param[out] value 寄存器数值,允许的类型有bool/int/float
    * @param[out] ec 错误码
    */
   template<typename T>
   void readRegister(const std::string &name, unsigned index, T &value, error_code &ec) noexcept;

#include <string> // 引入字符串库
#include <vector> // 引入向量库
#include <system_error> // 引入系统错误库
#include <unordered_map> // 引入无序映射库
#include <variant> // 引入变体库
#include <iostream> // 引入输入输出流库

using error_code = std::error_code; // 定义 error_code 类型为 std::error_code

// 模拟寄存器存储
std::unordered_map<std::string, std::variant<bool, int, float, std::vector<bool>, std::vector<int>, std::vector<float>>> registers;

// 模拟错误码
enum class RegisterError {
    IndexOutOfRange, // 索引超出范围
    InvalidIndexForNonArray, // 非数组类型的无效索引
    RegisterNotFound, // 寄存器未找到
    InvalidType // 无效类型
};

// 创建错误码
std::error_code make_error_code(RegisterError e) {
    return std::error_code(static_cast<int>(e), std::generic_category()); // 将 RegisterError 转换为 std::error_code
}

template<typename T>
void readRegister(const std::string &name, unsigned index, T &value, error_code &ec) noexcept {
    auto it = registers.find(name); // 查找寄存器
    if (it == registers.end()) { // 如果寄存器未找到
        ec = make_error_code(RegisterError::RegisterNotFound); // 设置错误码为寄存器未找到
        return; // 返回
    }

    auto &reg = it->second; // 获取寄存器的值

    if (std::holds_alternative<T>(reg)) { // 如果寄存器的值类型为 T
        if (index > 0) { // 如果索引大于 0
            ec = make_error_code(RegisterError::InvalidIndexForNonArray); // 设置错误码为非数组类型的无效索引
            return; // 返回
        }
        value = std::get<T>(reg); // 获取寄存器的值
    } else if (std::holds_alternative<std::vector<T>>(reg)) { // 如果寄存器的值类型为 std::vector<T>
        auto &vec = std::get<std::vector<T>>(reg); // 获取寄存器的向量值
        if (index >= vec.size()) { // 如果索引超出向量大小
            ec = make_error_code(RegisterError::IndexOutOfRange); // 设置错误码为索引超出范围
            return; // 返回
        }
        value = vec[index]; // 获取向量中的值
    } else {
        ec = make_error_code(RegisterError::InvalidType); // 设置错误码为无效类型
    }
}

int main() {
    // 示例用法
    registers["reg1"] = 42; // 设置寄存器 reg1 的值为 42
    registers["reg2"] = std::vector<int>{1, 2, 3, 4, 5}; // 设置寄存器 reg2 的值为向量 {1, 2, 3, 4, 5}

    int value; // 定义变量 value
    error_code ec; // 定义错误码 ec

    readRegister("reg1", 0, value, ec); // 读取寄存器 reg1 的值
    if (!ec) { // 如果没有错误
        std::cout << "reg1: " << value << std::endl; // 输出寄存器 reg1 的值
    } else {
        std::cout << "Error: " << ec.message() << std::endl; // 输出错误信息
    }

    readRegister("reg2", 2, value, ec); // 读取寄存器 reg2 的值
    if (!ec) { // 如果没有错误
        std::cout << "reg2[2]: " << value << std::endl; // 输出寄存器 reg2 的值
    } else {
        std::cout << "Error: " << ec.message() << std::endl; // 输出错误信息
    }

    return 0; // 返回 0
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值