当前位置: 首页 > article >正文

现代C++ 21 any

文章目录

      • 1. **概述**
      • 2. **成员函数**
        • 2.1 **构造函数和析构函数**
        • 2.2 **修改器函数**
        • 2.3 **观察者函数**
      • 3. **非成员函数**
      • 4. **辅助类**
      • 5. **示例代码**
        • 示例 1:基本用法
        • 输出:
        • 示例 2:使用 `std::any_cast` 访问值
        • 输出:
        • 示例 3:使用 `std::any_cast` 获取指针
        • 输出:
        • 示例 4:使用 `std::make_any` 创建 `std::any` 对象
        • 输出:
        • 示例 5:使用 `reset` 清空 `std::any` 对象
        • 输出:
      • 6. **总结**

std::any 是 C++17 引入的一个类,用于表示一个类型安全的容器,可以存储任何可复制构造类型的单个值。它提供了一种灵活的方式来处理不同类型的对象,而不需要提前知道具体的类型。 std::any 的设计目标是提供一种通用的、类型安全的方式来进行值的存储和访问。

1. 概述

std::any 的定义如下:

class any;
  • std::any 可以存储任何满足构造函数要求的类型的实例,或者为空。
  • 存储的实例称为包含对象
  • 如果两个 std::any 对象的状态都为空,或者两个状态都不为空且包含的对象是等价的,则这两个状态是等价的。
  • std::any 鼓励实现避免对小型对象进行动态分配,但这可能只适用于 std::is_nothrow_move_constructible 返回 true 的类型。

2. 成员函数

2.1 构造函数和析构函数
  • 默认构造函数:创建一个空的 std::any 对象。
  • 带参数的构造函数:接受一个值或引用,初始化 std::any 以包含该值。
  • 赋值操作符:将一个 std::any 的内容赋值给另一个 std::any,或者将一个值赋值给 std::any
  • 析构函数:销毁 std::any 对象及其包含的值。
2.2 修改器函数
  • emplace():就地构造 std::any 中的值,避免不必要的拷贝或移动。
  • reset():销毁 std::any 中的包含对象,使其变为空状态。
  • swap():交换两个 std::any 对象的内容。
2.3 观察者函数
  • has_value():检查 std::any 是否包含值。如果包含值,返回 true;否则返回 false
  • type():返回 std::any 中包含值的 typeid,如果 std::any 为空,则返回 typeid(void)

3. 非成员函数

  • std::swap(std::any):专门化 std::swap 算法,用于交换两个 std::any 对象的内容。
  • std::make_any<T>(args...):方便的函数模板,用于创建 std::any 对象,并直接构造其包含的值。
  • std::any_cast<T>(std::any):类型安全的访问 std::any 中的包含对象。std::any_cast 可以用于获取值、指针或引用。如果类型不匹配,抛出 std::bad_any_cast 异常。

4. 辅助类

  • std::bad_any_cast:当 std::any_cast 的返回值形式在类型不匹配时抛出的异常。

5. 示例代码

示例 1:基本用法
#include <iostream>
#include <any>
#include <typeinfo>

int main() {
    // 创建一个 std::any 对象并存储 int 类型的值
    std::any a = 42;
    std::cout << "Type: " << a.type().name() << ", Value: " << std::any_cast<int>(a) << '\n';

    // 修改为 double 类型的值
    a = 3.14;
    std::cout << "Type: " << a.type().name() << ", Value: " << std::any_cast<double>(a) << '\n';

    // 修改为 bool 类型的值
    a = true;
    std::cout << "Type: " << a.type().name() << ", Value: " << std::any_cast<bool>(a) << '\n';

    return 0;
}
输出:
Type: i, Value: 42
Type: d, Value: 3.14
Type: b, Value: true
示例 2:使用 std::any_cast 访问值
#include <iostream>
#include <any>
#include <string>

int main() {
    // 创建一个 std::any 对象并存储 string 类型的值
    std::any a = std::string("Hello, World!");

    // 使用 std::any_cast 获取值
    if (a.has_value()) {
        std::string value = std::any_cast<std::string>(a);
        std::cout << "Value: " << value << '\n';
    }

    // 尝试访问不存在的类型,会抛出 std::bad_any_cast 异常
    try {
        int value = std::any_cast<int>(a);
    } catch (const std::bad_any_cast& e) {
        std::cout << "Error: " << e.what() << '\n';
    }

    return 0;
}
输出:
Value: Hello, World!
Error: bad any_cast
示例 3:使用 std::any_cast 获取指针
#include <iostream>
#include <any>
#include <string>

int main() {
    // 创建一个 std::any 对象并存储 int 类型的值
    std::any a = 42;

    // 使用 std::any_cast 获取指向值的指针
    if (a.has_value()) {
        int* p = std::any_cast<int>(&a);
        std::cout << "Pointer to value: " << *p << '\n';
    }

    // 修改为 double 类型的值
    a = 3.14;

    // 使用 std::any_cast 获取指向值的指针
    if (a.has_value()) {
        double* p = std::any_cast<double>(&a);
        std::cout << "Pointer to value: " << *p << '\n';
    }

    return 0;
}
输出:
Pointer to value: 42
Pointer to value: 3.14
示例 4:使用 std::make_any 创建 std::any 对象
#include <iostream>
#include <any>
#include <string>

int main() {
    // 使用 std::make_any 创建 std::any 对象并存储 string 类型的值
    std::any a = std::make_any<std::string>("Hello, World!");

    // 使用 std::any_cast 获取值
    if (a.has_value()) {
        std::string value = std::any_cast<std::string>(a);
        std::cout << "Value: " << value << '\n';
    }

    return 0;
}
输出:
Value: Hello, World!
示例 5:使用 reset 清空 std::any 对象
#include <iostream>
#include <any>

int main() {
    // 创建一个 std::any 对象并存储 int 类型的值
    std::any a = 42;
    std::cout << "Type: " << a.type().name() << ", Value: " << std::any_cast<int>(a) << '\n';

    // 清空 std::any 对象
    a.reset();
    if (!a.has_value()) {
        std::cout << "No value\n";
    }

    return 0;
}
输出:
Type: i, Value: 42
No value

6. 总结

std::any 是 C++17 引入的一个非常灵活的工具,特别适用于需要存储和处理不同类型值的场景。它的主要特点包括:

  • 类型安全:通过 std::any_cast 提供了类型安全的访问方式,确保只能访问与实际存储类型匹配的值。
  • 灵活性:可以存储任何可复制构造类型的值,甚至可以在运行时动态改变存储的类型。
  • 性能优化:鼓励实现避免对小型对象进行动态分配,减少内存开销。
  • 简洁易用:提供了简单的接口来管理值的存储、访问和修改。

如果你有更多具体的问题或需要进一步的帮助,请随时提问!


http://www.kler.cn/a/430122.html

相关文章:

  • 51单片机 和 STM32 在硬件操作上的差异
  • CSS——22.静态伪类(伪类是选择不同元素状态)
  • 人工智能与物联网:智慧城市的未来
  • HTTP-响应协议
  • PLC实现HTTP协议JSON格式数据上报对接的参数配置说明
  • Typescript使用指南
  • 《筑牢网络安全防线:守护数字时代的生命线》
  • 阿里云ack部署rabbitmq集群
  • 网络原理之 TCP 协议
  • 启动hbase后没有hmaster进程
  • 二一(GIT4)、echarts(地图)、黑马就业数据平台(学生页-增 删 改)
  • 【论文阅读】Fifty Years of the ISCA: A Data-Driven Retrospective
  • 什么是厄尔米特(Hermitian)矩阵?
  • PHP:将数据传递给Grid++Report模板进行打印
  • 棋牌项目Go的日志打印问题
  • workflow笔记
  • WebSocket 经验与最佳实践
  • 《跨越平台壁垒:C++ 人工智能模型在移动设备的部署之路》
  • java+ssm+mysql校园物品租赁网
  • C#请求https提示未能为 SSL/TLS 安全通道建立信任关系
  • XREAL在日本AR市场成功的策略分析
  • Mysql | 尚硅谷 | 第02章_MySQL环境搭建
  • linux 安装 vsftpd 服务以及配置全攻略,vsftpd 虚拟多用户多目录配置,为每个用户配置不同的使用权限
  • 【前端】深度解析 JavaScript 中的 new 关键字与构造函数
  • 【ETCD】【源码阅读】configurePeerListeners() 函数解析
  • 数据结构——哈夫曼树